2016-11-15 121 views
1

我試圖用字典來計算給定字符串的詞頻。說:詞頻與詞典理解

s = 'I ate an apple a big apple' 

我知道計算詞頻的最佳方法可能是使用collections.Counter。但我想知道我是否可以通過使用詞典理解來解決這個問題。

我原來的方法(無字典解析)是

dict = {} 
for token in s.split(" "): 
    dict[token] = dict.get(token, 0) + 1 

,它工作正常:

dict 
{'I': 1, 'a': 1, 'an': 1, 'apple': 2, 'ate': 1, 'big': 1} 

我試圖使用字典理解這一點,像

dict = {} 
dict = {token: dict.get(token, 0) + 1 for token in s.split(" ")} 

但是這不起作用。

dict 
{'I': 1, 'a': 1, 'an': 1, 'apple': 1, 'ate': 1, 'big': 1} 

字典理解有什麼問題?是否因爲我在理解中使用了自己,所以每次我在dict.get('apple', 0)理解時,我會得到0?但是,我不知道如何測試這個,所以我不是100%確定的。

P.S.如果它有什麼區別,我正在使用python 3.

+2

這是什麼'collections.Counter'(一個字典子類型)很久以前解決了 –

+1

我不會使用字典作爲變量名稱,因爲它是一個內置的,你可以通過這樣做破壞 – e4c5

+1

變量'dict' isn在理解完全計算之前不會進行更新,所以「字典」。get(token,0)'在理解中只會查詢前一行的空字典。 – khelwood

回答

1

如果你通過操作來檢查你的代碼操作,你會看到什麼是錯誤的。

首先您將dict設置爲空字典。 (正如在評論中提到的,將它用於你自己的變量名是個不錯的主意,但這不是問題。)

其次,你的詞典理解被評估。此時名稱dict仍指空字典。所以每次你做dict.get(whatever, 0)時,它總會得到默認值。

最後,將您填充的字典重新分配到名稱dict,替換之前存在的空字段。

1

你也可以使用list.count(),如:

s = 'I ate an apple a big apple' 

print {token: s.split().count(token) for token in set(s.split())} 
0

爲了您的字典解析工作,你需要內部本身的理解的參考。像這樣的東西會工作

{token: __me__.get(token, 0) + 1 for token in s.split(" ")} 

如果有作爲「__me__」引用正在興建的理解這樣的事情。在Python 3中,沒有文檔記錄的方式來執行此操作。

根據this answer,可以在Python 2.5,2.6中使用未公開的「實現工件」(Python用戶不應該依賴它)來編寫自引用列表理解。 Python 3中的字典解析也可能存在類似的黑客攻擊。