2011-11-28 27 views
3

爲了計算詞頻,我使用python將文本文件中的句子中的單詞轉換爲列表中的單個標記。我無法將不同的句子轉換爲單個列表。這是我做的:將文件中的語句轉換爲列表中的詞語標記

f = open('music.txt', 'r') 
sent = [word.lower().split() for word in f] 

這給了我下面的列表:

[['party', 'rock', 'is', 'in', 'the', 'house', 'tonight'], 
['everybody', 'just', 'have', 'a', 'good', 'time'],...] 

由於文件中的句子分別放在不同的線,它返回列表的列表和defaultdict無法識別個人令牌數。

它嘗試下面的列表中理解到的標記在不同的列表中分離並返回一個列表,但它返回一個空的列表,而不是:

sent2 = [[w for w in word] for word in sent] 

有沒有辦法做到這一點使用列表內涵?或者也許更簡單的方法?

+1

@Sven Marnach的解決方案是一個很好的解決方案。想要解除嵌套列表問題的一般解決方案是使用'itertools.chain()'。參見http://ideone.com/g4YMu –

回答

4

只需使用嵌套循環列表解析裏:

sent = [word for line in f for word in line.lower().split()] 

有一些替代這種方法,例如使用itertools.chain.from_iterable(),但我覺得嵌套循環在這種情況下容易得多。

0

列表解析可以完成這項工作,但會積累內存中的所有內容。對於大量投入,這可能是一個不可接受的成本。以下解決方案不會在內存中累積大量數據,即使是大型文件也是如此。最終產品是形式爲{token: occurrences}的字典。

import itertools 

def distinct_tokens(filename): 
    tokendict = {} 
    f = open(filename, 'r') 
    tokens = itertools.imap(lambda L: iter(L.lower.split()), f) 
    for tok in itertools.chain.from_iterable(tokens): 
    if tok in tokendict: 
     tokendict[tok] += 1 
    else: 
     tokendict[tok] = 1 
    f.close() 
    return tokendict 
+0

'iflatten()'已經存在於標準庫中。它被稱爲'itertools.chain.from_iterable()'。 –

+0

更新了我的答案中的代碼。 – wberry

1

只是讀取整個文件到內存中,A S一個字符串,並應用split一次TOT帽子字符串。 在這種情況下,不需要逐行讀取文件。

因此你的核心可短爲:

sent = open("music.txt").read().split() 

(如關閉文件,檢查錯誤有幾個細微,轉碼稍微大一點,當然)

既然你想要計算字頻率,您可以使用collections.Counter類爲:

from collections import Counter 
counter = Counter() 
for word in open("music.txt").read().split(): 
    counter[word] += 1 
+0

你不會初始化'counter'。並且你不需要循環 - 'Counter(open(「music.txt」)。read().split())'就足夠了。 –

+0

@SvenMarnach:啊..謝謝,我沒記得如何以這種方式初始化櫃檯。另一方面,按照我所做的方式假設不存在的鍵包含'0' - 所以此代碼可以工作。 – jsbueno

+0

我的意思是 - 你的代碼缺少'counter = Counter()'行。我知道這是一個微不足道的評論,我* *已經*提出了你的答案。 :)(我以前的評論的第二部分與第一部分無關。) –

相關問題