2016-11-15 118 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中的字典解析也可能存在类似的黑客攻击。