Deu*_*ius 4 python dictionary defaultdict
我正在尝试优化脚本的性能,该脚本在给出的每个单词的词典中查找相似的单词.
每个唯一的单词将被分成字母n-gram,并且对于每个n-gram,词典返回包含相同字母n-gram的单词列表.然后将此列表中的每个单词作为键添加到字典中,并将其值加1.这给了我一个具有相应频率分数的类似单词的字典.
word_dict = {}
get = word_dict.get
for letter_n_gram in word:
for entry in lexicon[n_gram]:
word_dict[entry] = get(entry, 0) + 1
Run Code Online (Sandbox Code Playgroud)
这个实现有效,但是通过切换dictfor 可以更快地运行脚本collections.defaultdict.
word_dd = defaultdict(int)
for letter_n_gram in word:
for entry in lexicon[n_gram]:
word_dd[entry] += 1
Run Code Online (Sandbox Code Playgroud)
没有其他代码被更改.
我的印象是两个代码片段(最重要的是分数添加)应该以完全相同的方式工作,即如果密钥存在,将其值增加1,如果它不存在,则创建密钥并将值设置为1.
但是,在运行新代码之后,某些键的值为0,我觉得这在逻辑上是不可能的.
我的逻辑或defaultdict功能知识是否有缺陷?如果没有,如何将任何值word_dd设置为0?
编辑:我也非常确定脚本中没有其他部分会扭曲这些结果,因为我使用以下代码在显示代码后立即测试字典:
for item in word_dd.iteritems():
if item[1] == 0:
print "Found zero value element"
break
Run Code Online (Sandbox Code Playgroud)
当您访问a中的某个键时defaultdict,如果它不存在,则会自动创建该键.由于我们具有int默认的工厂函数,因此它会创建密钥并提供默认值0.
from collections import defaultdict
d = defaultdict(int)
print d["a"]
# 0
print d
# defaultdict(<type 'int'>, {'a': 0})
Run Code Online (Sandbox Code Playgroud)
因此,在访问密钥之前,您应确保它存在于defaultdict实例中,如下所示
print "a" in d
# False
Run Code Online (Sandbox Code Playgroud)
任何项目对密钥的访问都将实现该值:
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> d['foo']
0
Run Code Online (Sandbox Code Playgroud)
使用包含来测试存在而不是:
>>> 'bar' in d
False
>>> 'foo' in d
True
Run Code Online (Sandbox Code Playgroud)
既然你在计算n-gram,你可能也想看一下collections.Counter():
from collections import Counter
word_counter = Counter()
for letter_n_gram in word:
word_counter.update(lexicon[n_gram])
Run Code Online (Sandbox Code Playgroud)
其中Counter.update()将更新lexicon[n_gram]表达式返回的所有条目的计数.
就像defaultdict(int),Counter()对象自动实现值,默认为整数0.
| 归档时间: |
|
| 查看次数: |
4280 次 |
| 最近记录: |