2017-03-24 84 views
1

我試圖將文本輸入轉換爲保留其結構的嵌套列表。目前我有一個函數需要一個文本和一個期望的「深度」,並輸出這個深度的嵌套列表,在每一個新行,句子或單詞處打破文本。如何將文本轉換爲嵌套列表

def text_split(text, depth): 
    depth_list = [' ', '.', '\n'] 
    if isinstance(text, str): 
     text = text.strip('. ') 
     text = text.split(depth_list[depth]) 
    if depth >= 0: 
     depth -= 1 
     for ix, item in enumerate(text): 
       item = item.strip('. ') 
       text[ix] = text_split(item, depth) 
    return text 

這需要文本,如

text1 = """acabei de ler um livro. um diário. 
mas a liberdade sempre chamou fountaine mais forte. 
a cada viagem fountaine ía mais longe. aprendeu a andar de bicicleta e viajou o sul da frança. 

esse é o tipo de pergunta feita na última edição do prêmio Loebner, em que participantes precisam responder à algumas questões feitas pelo júri. 

o que tem de especial nessa competição é que ela não é para humanos, mas sim para robôs. o prêmio Loebner é uma implementação do teste de Turing. 

""" 

[ [[['acabei'], ['de'], ['ler'], ['um'], ['livro']], [['um'], ['diário']]], 
[ [ ['mas'], 
     ['a'], 
     ['liberdade'], 
     ['sempre'], 
     ['chamou'], 
     ['fountaine'], 
     ['mais'], 
     ['forte']]], 
[ [ ['a'], 
     ['cada'], 
     ['viagem'], 
     ['fountaine'], 
     ['ía'], 
     ['mais'], 
     ['longe']], 
    [ ['aprendeu'], 
     ['a'], 
     ['andar'], 
     ['de'], 
     ['bicicleta'], 
     ['e'], 
     ['viajou'], 
     ['o'], 
     ['sul'], 
     ['da'], 
     ['frança']]], 
[[['']]], ... ]]]] 

現在這可能不是這樣做的最好,最優雅的方式,它有一些問題,如在\n被分割之後出現的[[['']]](這可以通過使用.splitlines()來解決,但我無法找到一種很好的調用方式這個方法在遞歸函數中)。

這樣做的更好方法是什麼?我應該使用嵌套列表嗎? (我打算在此後迭代)。感謝您的建議!

+0

你爲什麼希望所有的深度,例如爲什麼列表中只有一個單詞呢? – AChampion

+0

@AChampion確實,這是沒有必要保持結構!這不是要求。感謝您指出! –

回答

1

這是我能想出以滿足您的需求的最佳:

text = [] 
for line in text1.split('\n'): 
    sentences = [] 
    for sentence in line.split('.'): 
    words = [] 
    for word in sentence.split(' '): 
     if len(word.strip()) > 0: # make sure we are adding something 
     words.append(word.strip()) 
    if len(words) > 0: 
     sentences.append(words) 
    if len(sentences) > 0: 
    text.append(sentences) 

利用這一點,我們有數組定義良好的結構,我們可以肯定的是,我們沒有任何空白或空陣列。此外,在這裏使用遞歸併不是一件好事,因爲你有一個清晰的文本結構。你知道遞歸的深度不會超過3級。另外,如果你想要一個遞歸的版本,你應該在你的問題中說明它,並清除需求。

+0

更清晰!我去了一個遞歸函數,因爲我想我可能會在稍後擴展我的depth_list,但是想一想,我認爲它不會比_deeper_更進一步:P謝謝! –

+0

沒問題!請記住接受答案,如果它回答了你的問題 – meyer9

+0

我做了一些改變 'for line in text.splitlines():'splits直接刪除\ n \ n(不需要長度檢查) '如果stripped_word:'比檢查長度快(並且結果相同,我希望) –

1

您可以使用嵌套列表理解只是用你的標準拆分:

>>> [[s.split() for s in line.split('.') if s] for line in text1.split('\n') if line] 
[[['acabei', 'de', 'ler', 'um', 'livro'], ['um', 'diário']], 
[['mas', 'a', 'liberdade', 'sempre', 'chamou', 'fountaine', 'mais', 'forte']], 
[['a', 'cada', 'viagem', 'fountaine', 'ía', 'mais', 'longe'], 
    ['aprendeu', 'a', 'andar', 'de', 'bicicleta', 'e', 'viajou', 'o', 'sul', 'da', 'frança']], 
... 
+0

感謝您的幫助!我只增加了另一層理解,以便我可以從單詞中刪除',',並將split('\ n')'更改爲'splitlines()',因爲它似乎更通用: '[[[w.strip(',。;')for s.split()if w] for s in line.split('。')if s] for line in text.splitlines()if line] ' –