def tf(tokens):
""" Compute TF
Args:
tokens (list of str): input list of tokens from tokenize
Returns:
dictionary: a dictionary of tokens to its TF values
"""
li = {}
total = len(tokens)
li = {token: 1 if not token in li else li[token] + 1 for token in tokens }
return {token: li[token]/ float(total) for token in li}
基本上,我想要一个字典,其中令牌是键,值是令牌列表中该令牌的频率。
我希望我的理解能够检查令牌是否已经在li中。如果它只是将其值增加1,如果不是,则创建它并将其值设置为1.
出于某种原因,无论在令牌列表中出现多少次,每个键的最终值都为(1)。
你能帮我看看为什么会这样吗?
我可以通过循环解决它,但我想掌握字典理解。
非常感谢你!
答案 0 :(得分:2)
列表/字典理解之类的理解表达式是构建器表达式,并且在完全计算表达式之前不会构造对象。在生成的字典的引用之后,将符号名称赋值给它。
在您的特定示例中,您指的是符号li
,它引用了对象空字典。因此,在评估表达式时,li
继续引用一个空字典,这意味着,字典理解可以等效地写为
li = {token: 1 if not token in {} else l{}[token] + 1 for token in tokens }
或简化为空字典的成员资格测试始终为假
li = {token: 1 for token in tokens }
您需要的是已有的库实用程序或基于状态的解决方案。
幸运的是,标准库collections提供了一个名为counter的函数,该函数是为此目的而编写和设计的。
这只是你的功能
def tf(tokens):
from collections import Counter
""" Compute TF
Args:
tokens (list of str): input list of tokens from tokenize
Returns:
dictionary: a dictionary of tokens to its TF values
"""
return Counter(tokens)
基于状态的解决方案只需要每个唯一事件的外部计数器
def tf(tokens):
from collections import defaultdict
""" Compute TF
Args:
tokens (list of str): input list of tokens from tokenize
Returns:
dictionary: a dictionary of tokens to its TF values
"""
counter = defaultdict(int)
for token in tokens:
counter[token] += 1
return counter
或者如果您不打算使用defaultdict
def tf(tokens):
from collections import defaultdict
""" Compute TF
Args:
tokens (list of str): input list of tokens from tokenize
Returns:
dictionary: a dictionary of tokens to its TF values
"""
counter = {}
for token in tokens:
counter[token] = counter.get(token, 0) + 1
return counter
答案 1 :(得分:1)
字典理解首先执行,生成 new 字典对象。只有当该表达式完成时,才li
绑定到该新词典。
换句话说,这就是幕后发生的事情,没有_result
在循环中可供参考:
li = {}
_result = {}
for token in tokens:
_result[token] = 1 if not token in li else li[token] + 1
li = _result
由于li
在整个循环期间为空,token in li
始终为False
。字典理解本身工作得很好。
如果您想计算值,可以只是使它成为显式循环:
li = {}
for token in tokens:
li[token] = 1 if not token in li else li[token] + 1
但你最好使用collections.Counter()
object,它封装了相同的程序并在顶部添加了其他功能:
from collections import Counter
def tf(tokens):
li = Counter(tokens)
total = float(len(tokens))
return {token: li[token] / total for token in li}
答案 2 :(得分:0)
使用Counter词典:
from collections import Counter
li = Counter(tokens)
使用普通字典需要使用for循环和dict.setdefault
:
li = {}
for t in tokens:
li.setdefault(t,0) # if key not yet added create key/value pairing
li[t] += 1 # increment count for the key
你不能增加dict理解中的计数,因为你总是会得到1
的计数,你需要一个Counter dict或一个显式循环来处理重复键,因为li指的是空字典直到理解完成。
if not token in li
始终为True,因此您始终将值设置为1
所以在你的函数中使用Couner dict并遍历项目:
def tf(tokens):
""" Compute TF
Args:
tokens (list of str): input list of tokens from tokenize
Returns:
dictionary: a dictionary of tokens to its TF values
"""
total = float(len(tokens))
li = Counter(tokens)
return {token: v / float(total) for token,v in li.iteritems()}
答案 3 :(得分:0)
def tf(tokens):
mydic = {}
for key in tokens:
if key not in mydic:
mydic[key] = 1
else:
mydic[key] = mydic[key] + 1
d2 = dict((k, float(v)/len(tokens)) for k,v in mydic.items())
return d2