是的,这是预期的;该
Counter()构造
的用途
Counter.update(),它使用
self.get()加载初始值,而不是依靠
__missing__。
此外,
defaultdict
__missing__工厂完全由C代码处理,尤其是在使用其他类似的类型
int()(本身由C实现)时。
Counter源是纯Python,因此该
Counter.__missing__方法需要Python框架才能执行。
由于
dict.get()仍在C中处理,因此对于,构造器方法是更快的方法
Counter(),只要您使用相同的技巧
Counter.update()和别名
self.get作为本地优先项即可:
>>> import timeit>>> import random>>> import sys>>> sys.version_infosys.version_info(major=2, minor=7, micro=9, releaselevel='final', serial=0)>>> to_count = [random.randint(0, 100) for r in range(60)]>>> timeit.timeit('for i in to_count: c[i] += 1',... 'from collections import Counter; from __main__ import to_count; c = Counter()',... number=10000)0.2510359287261963>>> timeit.timeit('for i in to_count: c[i] = c_get(i, 0) + 1',... 'from collections import Counter; from __main__ import to_count; c = Counter(); c_get = c.get',... number=10000)0.20978617668151855两者
defaultdict并
Counter为他们的功能,而不是他们的表现内置有用的类; 不依赖
__missing__钩子可以更快:
>>> timeit.timeit('for i in to_count: d[i] = d_get(i, 0) + 1',... 'from __main__ import to_count; d = {}; d_get = d.get',... number=10000)0.11437392234802246这是使用别名
dict.get()方法以实现最大速度的常规词典。但是随后,您还必须重新实现
Counter或
Counter.most_common()方法的bag行为。该
defaultdict用例去的方式数不胜数。
在Python
3.2中,
Counter()通过添加一个处理这种情况的C库来更新速度。参见问题10667。在Python
3.4上进行测试,
Counter()构造函数现在击败了别名
dict.get情况:
>>> timeit.timeit('Counter(to_count)',... 'from collections import Counter; from __main__ import to_count',... number=100000)0.8332311600097455>>> timeit.timeit('for i in to_count: d[i] = d_get(i, 0) + 1',... 'from __main__ import to_count; d = {}; d_get = d.get',... number=100000)0.961191965994658>>> import sys>>> sys.version_infosys.version_info(major=3, minor=4, micro=2, releaselevel='final', serial=0)(注意:要获得有意义的计时结果,迭代次数从10k增加到100k;因此,如果将上述
dict.get()情况与上述情况进行比较,则需要在计时中乘以10倍,即1.144秒)。



