Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是Python中的defaultdict';s collections模块真的比使用setdefault快吗?_Python_Collections_Defaultdict_Setdefault_Python Collections - Fatal编程技术网

是Python中的defaultdict';s collections模块真的比使用setdefault快吗?

是Python中的defaultdict';s collections模块真的比使用setdefault快吗?,python,collections,defaultdict,setdefault,python-collections,Python,Collections,Defaultdict,Setdefault,Python Collections,我见过其他Python程序员在以下用例中使用collections模块中的defaultdict: from collections import defaultdict s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] def main(): d = defaultdict(list) for k, v in s: d[k].append(v) 我通常使用set

我见过其他Python程序员在以下用例中使用collections模块中的defaultdict:

from collections import defaultdict

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

def main():
    d = defaultdict(list)
    for k, v in s:
        d[k].append(v)
我通常使用setdefault来解决这个问题:

def main():
    d = {}
    for k, v in s:
        d.setdefault(k, []).append(v)
事实上,文档确实如此,但我在测试自己时看到了相反的情况:

$ python -mtimeit -s "from withsetdefault import main; s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)];" "main()"
100000 loops, best of 3: 4.51 usec per loop
$ python -mtimeit -s "from withdefaultdict import main; s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)];" "main()"
100000 loops, best of 3: 5.38 usec per loop
我设置测试的方式有问题吗

作为参考,我使用的是Python 2.7.3[GCC 4.2.1(Apple Inc.build 5666)

是的,有一些“错误”:

您已经创建了
(默认值)dict
插入语句而不是设置。构造一个新的
defaultdict
比普通的
dict
更昂贵,通常这不是您应该在程序中分析的瓶颈-毕竟,您只构建了一次数据结构,但使用了很多次

如果您进行如下测试,您会发现
defaultdict
操作确实更快:

>>> import timeit
>>> setup1 = """from collections import defaultdict
... s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
... d = defaultdict(list)"""
>>> stmt1 = """for k, v in s:
...     d[k].append(v)"""
>>> setup2 = """s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
... d = {}"""
>>> stmt2 = """for k, v in s:
...     d.setdefault(k, []).append(v)"""
>>> timeit.timeit(setup=setup1, stmt=stmt1)
1.0283400125194078
>>> timeit.timeit(setup=setup2, stmt=stmt2)
1.7767367580925395

Win7 x64上的Python 2.7.3。

是否有一个测试文件包含
s=[('yellow',1),('blue',2),('yellow',3),('blue',4),('red',1)]
另一个没有的地方?@Claudiu:仔细阅读时间线。你需要使用更大的测试集,其中每个键有2个以上的值。@MartijnPieters:我有。我不知道使用setDefault.py的
和使用defaultdict.py的
中有什么。如果其中一个包含该行,而另一个不包含该行,这可能是错误的原因当我从test语句中删除defaultdict构造函数时,无论数据大小如何,使用setdefault肯定比使用setdefault更快。您只谈论构造(默认值)dict是一个区别,但我想说,您还有第二个可能很重要的区别:在原始版本中,60%的键是新的,需要插入,并使用了
[]
。在您的版本中,由于每个片段重复了一百万次,几乎为0%。