【问题标题】:Is the defaultdict in Python's collections module really faster than using setdefault?Python 集合模块中的 defaultdict 真的比使用 setdefault 快吗?
【发布时间】:2012-09-15 09:04:00
【问题描述】:

我看到其他 Python 程序员使用集合模块中的 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)

文档实际上是 claim that using defaultdict is faster,但我在测试自己时看到了相反的情况:

$ 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)

【问题讨论】:

  • 一个测试文件是否包含s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] 而另一个没有?
  • @Claudiu:仔细阅读时间线。
  • 您需要使用 很多 个更大的测试集,其中每个键有 2 个以上的值。
  • @MartijnPieters:我做到了。我不知道withsetdefault.pywithdefaultdict.py 中有什么。如果其中一个包含该行而另一个不包含该行,则可能会导致差异

标签: python collections defaultdict setdefault python-collections


【解决方案1】:

是的,有些“错误”:

您已将(default)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。

【讨论】:

  • 谢谢蒂姆!当我从测试语句中删除 defaultdict 构造函数时,使用 setdefault 肯定更快......无论数据大小如何。
  • 您只谈论构造(默认)dict 的区别,但我想说您还有第二个可能很重要的区别:在原始密钥中,60% 的密钥是新的,并且需要插入并使用[]。在你的版本中,由于每个 sn-p 重复一百万次,它几乎是 0%。
猜你喜欢
  • 2016-01-20
  • 2019-04-30
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 2013-06-28
  • 2018-11-08
  • 2011-09-28
  • 2012-09-16
相关资源
最近更新 更多