gpt4 book ai didi

python - OrderedDict vs defaultdict vs dict

转载 作者:IT老高 更新时间:2023-10-28 21:47:11 27 4
gpt4 key购买 nike

在 python 的库中,我们现在有两个 Python 字典实现,它们在原生 dict 类型之上继承了 dict

Python 的拥护者总是更喜欢 defaultdict 而不是尽可能使用 dict.setdefault。甚至doc引用 这种技术比使用 dict.setdefault() 的等效技术更简单、更快:

以类似的方式,由于字典不保持顺序,因此尽可能首选使用 OrderedDict 而不是使用 dict 然后对项目进行排序以作为替代用法。

在上述两种情况下,代码肯定更干净,但代价是性能损失。

在回答和评论其中一个问题时 python unique list based on item ,当使用 defaultdictOrderedDict 时,我偶然发现了原生 dict 的性能损失。似乎数据的大小对于 dict 解决方案相对于其他解决方案的性能优势也不是无关紧要的。

我相信应该有一种——最好只有一种——明显的方法。,那么首选的方法是什么?

最佳答案

没有一个单一的答案,也没有一个真实且唯一的字典。在众多变量中,它取决于:

  1. 数据集的大小;
  2. 唯一键的数量与数据映射集中重复键的数量;
  3. defaultdict 底层工厂的速度;
  4. OrderDict 的速度与稍后的一些订购步骤;
  5. Python 版本。

讨厌概括,但这里有一些概括:

  1. 声明 这种技术比使用 dict.setdefault() 的等效技术更简单、更快 是完全错误的。这取决于数据;
  2. setdefault 对于小数据集更快更简单;
  3. defaultdict 对于具有更多同质键集的较大数据集(即,添加元素后dict有多短)更快;
  4. setdefault 具有更多异构键集的优势;
  5. 这些结果对于 Python 3 和 Python 2 是不同的;
  6. OrderedDict 在所有情况下都较慢,除了依赖于顺序的算法并且顺序不易重构或排序;
  7. 对于大多数 dict 操作而言,Python 3 通常更快;
  8. Python 3.6 的 dict 现在按插入顺序排序(降低了 OrderedDict 的用处)。

唯一的事实:视情况而定!这三种技术都很有用。

下面是一些计时代码:

from __future__ import print_function
from collections import defaultdict
from collections import OrderedDict

try:
t=unichr(100)
except NameError:
unichr=chr

def f1(li):
'''defaultdict'''
d = defaultdict(list)
for k, v in li:
d[k].append(v)
return d.items()

def f2(li):
'''setdefault'''
d={}
for k, v in li:
d.setdefault(k, []).append(v)
return d.items()

def f3(li):
'''OrderedDict'''
d=OrderedDict()
for k, v in li:
d.setdefault(k, []).append(v)
return d.items()


if __name__ == '__main__':
import timeit
import sys
print(sys.version)
few=[('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
fmt='{:>12}: {:10.2f} micro sec/call ({:,} elements, {:,} keys)'
for tag, m, n in [('small',5,10000), ('medium',20,1000), ('bigger',1000,100), ('large',5000,10)]:
for f in [f1,f2,f3]:
s = few*m
res=timeit.timeit("{}(s)".format(f.__name__), setup="from __main__ import {}, s".format(f.__name__), number=n)
st=fmt.format(f.__doc__, res/n*1000000, len(s), len(f(s)))
print(st)
s = [(unichr(i%0x10000),i) for i in range(1,len(s)+1)]
res=timeit.timeit("{}(s)".format(f.__name__), setup="from __main__ import {}, s".format(f.__name__), number=n)
st=fmt.format(f.__doc__, res/n*1000000, len(s), len(f(s)))
print(st)
print()

Python 2.7 结果:

2.7.5 (default, Aug 25 2013, 00:04:04) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]
defaultdict: 10.20 micro sec/call (25 elements, 3 keys)
defaultdict: 21.08 micro sec/call (25 elements, 25 keys)
setdefault: 13.41 micro sec/call (25 elements, 3 keys)
setdefault: 18.24 micro sec/call (25 elements, 25 keys)
OrderedDict: 49.47 micro sec/call (25 elements, 3 keys)
OrderedDict: 102.16 micro sec/call (25 elements, 25 keys)

defaultdict: 28.28 micro sec/call (100 elements, 3 keys)
defaultdict: 79.78 micro sec/call (100 elements, 100 keys)
setdefault: 45.68 micro sec/call (100 elements, 3 keys)
setdefault: 68.66 micro sec/call (100 elements, 100 keys)
OrderedDict: 117.78 micro sec/call (100 elements, 3 keys)
OrderedDict: 343.17 micro sec/call (100 elements, 100 keys)

defaultdict: 1123.60 micro sec/call (5,000 elements, 3 keys)
defaultdict: 4250.44 micro sec/call (5,000 elements, 5,000 keys)
setdefault: 2089.86 micro sec/call (5,000 elements, 3 keys)
setdefault: 3803.03 micro sec/call (5,000 elements, 5,000 keys)
OrderedDict: 4399.16 micro sec/call (5,000 elements, 3 keys)
OrderedDict: 16279.14 micro sec/call (5,000 elements, 5,000 keys)

defaultdict: 5609.39 micro sec/call (25,000 elements, 3 keys)
defaultdict: 25351.60 micro sec/call (25,000 elements, 25,000 keys)
setdefault: 10267.00 micro sec/call (25,000 elements, 3 keys)
setdefault: 24091.51 micro sec/call (25,000 elements, 25,000 keys)
OrderedDict: 22091.98 micro sec/call (25,000 elements, 3 keys)
OrderedDict: 94028.00 micro sec/call (25,000 elements, 25,000 keys)

Python 3.3 结果:

3.3.2 (default, May 21 2013, 11:50:47) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))]
defaultdict: 8.58 micro sec/call (25 elements, 3 keys)
defaultdict: 21.18 micro sec/call (25 elements, 25 keys)
setdefault: 10.42 micro sec/call (25 elements, 3 keys)
setdefault: 14.58 micro sec/call (25 elements, 25 keys)
OrderedDict: 45.43 micro sec/call (25 elements, 3 keys)
OrderedDict: 92.69 micro sec/call (25 elements, 25 keys)

defaultdict: 20.47 micro sec/call (100 elements, 3 keys)
defaultdict: 77.48 micro sec/call (100 elements, 100 keys)
setdefault: 34.22 micro sec/call (100 elements, 3 keys)
setdefault: 54.86 micro sec/call (100 elements, 100 keys)
OrderedDict: 107.37 micro sec/call (100 elements, 3 keys)
OrderedDict: 318.98 micro sec/call (100 elements, 100 keys)

defaultdict: 714.70 micro sec/call (5,000 elements, 3 keys)
defaultdict: 3892.92 micro sec/call (5,000 elements, 5,000 keys)
setdefault: 1502.91 micro sec/call (5,000 elements, 3 keys)
setdefault: 2888.08 micro sec/call (5,000 elements, 5,000 keys)
OrderedDict: 3912.95 micro sec/call (5,000 elements, 3 keys)
OrderedDict: 14863.02 micro sec/call (5,000 elements, 5,000 keys)

defaultdict: 3649.02 micro sec/call (25,000 elements, 3 keys)
defaultdict: 22313.17 micro sec/call (25,000 elements, 25,000 keys)
setdefault: 7447.28 micro sec/call (25,000 elements, 3 keys)
setdefault: 18426.88 micro sec/call (25,000 elements, 25,000 keys)
OrderedDict: 19202.17 micro sec/call (25,000 elements, 3 keys)
OrderedDict: 85946.45 micro sec/call (25,000 elements, 25,000 keys)

关于python - OrderedDict vs defaultdict vs dict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19629682/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com