我正在尝试优化一个脚本的性能,该脚本为给定的每个单词在词典中查找相似单词。
每个唯一的单词都将被分割成字母 n-gram,并且对于每个 n-gram,词典将返回包含相同字母 n-gram 的单词列表。然后将此列表中的每个单词作为键添加到一个字典中,并将其值增加一。这样就可以得到具有相应频率分数的相似单词的字典。
每个唯一的单词都将被分割成字母 n-gram,并且对于每个 n-gram,词典将返回包含相同字母 n-gram 的单词列表。然后将此列表中的每个单词作为键添加到一个字典中,并将其值增加一。这样就可以得到具有相应频率分数的相似单词的字典。
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
这个实现方式是可行的,但是通过将dict
替换为collections.defaultdict
可以加快脚本运行速度。
word_dd = defaultdict(int)
for letter_n_gram in word:
for entry in lexicon[n_gram]:
word_dd[entry] += 1
没有其他代码被改变。
我原以为这两个代码片段(最重要的是添加分数)应该以完全相同的方式工作,即如果键存在,则将其值增加1,如果不存在,则创建键并将值设置为1。
然而,在运行新代码后,一些键的值为0,我认为这在逻辑上是不可能的。
我的逻辑或对defaultdict
功能的了解是否有误?如果不是,那么如何将word_dd
中的任何值设置为0?
编辑:我也非常确定脚本的其他部分不会影响这些结果,因为我立即使用以下方法测试字典:
for item in word_dd.iteritems():
if item[1] == 0:
print "Found zero value element"
break
word_dd ['nonesuch']
不会分配,但会为您创建值。 - Martijn Pietersdefaultdict
的理解似乎很好:您发布的代码不可能出现0 in word_dd.values()
为True的情形。您确定您在发布的两个代码片段之间没有涉及到word_dd
的任何代码吗?此外,只有当默认值计算代价昂贵时,默认字典才会比dict.get/dict.setdefault
快得多 - 常量整数明显不是。在这里考虑使用它的原因是它使您的代码更加 简单,而不是更快。 - lvc