在字典上进行迭代的最佳方式(性能方面)

时间:2019-10-03 22:53:18

标签: python performance dictionary iteration

This 建议.items()是迭代字典的最佳方法,因为它是pythonic。

就性能而言,以下哪一项是最佳的,为什么?

  1. for key in dic:
        value = dic[key]
    
  2. for key, value in dic.items():
    
  3. for key in dic.keys():
        value = dic[key]
    

4 个答案:

答案 0 :(得分:2)

基于timeit值:

要查找键和值,

from timeit import timeit

d = {i: i for i in range(100)}

def a():
    for key in d:
        d[key]
        pass

def b():
    for key, value in d.items():
        pass

def c():
    for key in d.keys():
        d[key]
        pass

for fn in [a, b, c]:
    print(fn.__name__, timeit(fn))


Solution 1 7.8113735559999995
Solution 2 2.6758934780000008
Solution 3 5.499667492

要找到键,

from timeit import timeit

d = {i: i for i in range(100)}

def a():
    for key in d:
        pass

def b():
    for key, value in d.items():
        pass

def c():
    for key in d.keys():
        pass

for fn in [a, b, c]:
    print(fn.__name__, timeit(fn))

Solution 1 1.5981329149999999
Solution 2 2.649033456
Solution 3 1.6517934609999996

因此,找到键的第一个解决方案最快,但是找到键和值的第二个解决方案最快。

答案 1 :(得分:1)

如果同时需要键和值,请使用for k, v in mydict.items():;迭代密钥,然后查找它意味着不必要地查找您可以通过.items()免费获得的信息。对于非常dict,它可能比for k in mydict:慢,然后再进行查找(这是因为创建项目视图的成本非常小,可能会超过很少的查询),但是对于dict的中等长度,.items()总是赢。

如果只需要键,for k in mydict:for k in mydict.keys():大致相同,尽管后者在Py3中要慢一点(由于需要构造键视图),并且可以显着在Py2上速度较慢(在Py2上它会通过键的副本生成临时list,而前一种方法是直接懒惰地迭代dict)。

答案 2 :(得分:1)

这类通用计时很少有用,因为性能是由特定于相关数据,应用程序和环境的更广泛的变量驱动的,但是为了提供一些简单的比较数据,此处提供了一些测试可以在您自己的环境中复制并尝试。

仅进行迭代而不访问dict值就不足为奇地表明,除了dict.items()稍稍落后之外,其他任何方法的性能差异都很小,因为它同时创建了键和值的视图(而其他方法显示的只是处理其中一个)。

from timeit import timeit

loop = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d: pass"""
print(timeit(stmt=loop, number=10000))
# 1.0733639170002789

keys = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d.keys(): pass"""
print(timeit(stmt=keys, number=10000))
# 1.0360493710004448

values = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.values(): pass"""
print(timeit(stmt=values, number=10000))
# 1.0380961279997791

items = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.items(): pass"""
print(timeit(stmt=items, number=10000))
# 1.2011308679993817

在访问每个键的值时进行迭代以试图平整公平地进行竞争,这表明dict.items()在您需要迭代访问和访问键和值时会稍快一些。

from timeit import timeit

loop = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d: d[k]"""
print(timeit(stmt=loop, number=10000))
# 1.4128917540001567

keys = """
d = dict(zip(range(1000), reversed(range(1000))))
for k in d.keys(): d[k]"""
print(timeit(stmt=keys, number=10000))
# 1.3668724469998779

items = """
d = dict(zip(range(1000), reversed(range(1000))))
for v in d.items(): pass"""
print(timeit(stmt=items, number=10000))
# 1.1864945030001763

答案 3 :(得分:-1)

出于两个原因,两个是您的最佳选择,

1)您可以同时获取键和值,从而节省了在需要时再次调用它的资源

2)如您所说,它是“ pythonic”的,是那里最快的方法。