繁体   English   中英

defaultdict vs dict元素初始化

[英]defaultdict vs dict element initialization

我正在尝试优化脚本的性能,该脚本在给出的每个单词的词典中查找相似的单词。

每个唯一的单词将被分成字母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

这个实现可以工作,但是通过切换collections.defaultdictdict可以更快地运行脚本。

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

当您访问defaultdict的密钥时,如果它不在那里,它将自动创建。 由于我们将int作为默认工厂函数,因此它会创建密钥并提供默认值0。

from collections import defaultdict
d = defaultdict(int)
print d["a"]
# 0
print d
# defaultdict(<type 'int'>, {'a': 0})

因此,在访问密钥之前,您应确保它存在于defaultdict实例中,如下所示

print "a" in d
# False

对密钥的任何项访问都将实现该值:

>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> d['foo']
0

使用包含来测试存在而不是:

>>> 'bar' in d
False
>>> 'foo' in d
True

由于你在计算n-gram,你可能想看看collections.Counter()

from collections import Counter

word_counter = Counter()
for letter_n_gram in word:
    word_counter.update(lexicon[n_gram])

其中Counter.update()将更新lexicon[n_gram]表达式返回的所有条目的计数。

defaultdict(int)Counter()对象自动实现值,默认为整数0

唉,我在代码中发现了错误。

由于在我的输入集中有许多随后的单词n-gram和相同的测试单词,我只是每个唯一的测试单词创建一个相似单词的字典。

然后,该字典用于其他目的,其中密钥被多次测试。 当然,如果字典是collections.defaultdict并且默认工厂未设置为None ,则可以创建零值元素。

然而,在每个主循环中进行零值元素的测试 - 因此找到在前一循环中创建的零值元素。

在将测试代码缩进到适当的部分之后,结果如预期的那样 - 在创建之后不会立即出现零值元素。

我想向所有人道歉,因为我的问题错误和不完整 - 其他人都无法找到错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM