繁体   English   中英

迭代字典的最佳方式(性能方面)

[英]Best way (performance-wise) to iterate over a dictionary

表明.items()是遍历字典的最佳方式,因为它是 Python 的。

性能方面,以下哪个是最好的,为什么?

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

基于 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

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

如果您需要键和值, for k, v in mydict.items(): ; 迭代键然后查找它意味着不必要地查找您可以使用.items()免费获得的信息。 对于非常短的dict ,它可能比for k in mydict:然后是查找(仅仅是因为创建项目视图的成本非常小,可能超过几次查找的成本),但是对于中等长度的dict , .items()将永远获胜。

如果您只需要密钥,则for k in mydict: for k in mydict.keys():中的 k 大致相同,尽管后者在 Py3 中稍慢一些(由于需要构建密钥视图)并且可以在 Py2 上显着变慢(它使用密钥副本创建一个临时list ,前一种方法直接懒惰地迭代dict )。

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

不出所料,只是在不访问 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

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

1)您可以获得键和值,因此您可以在需要时再次调用它来节省资源

2)就像你说的,它是“pythonic”,它是那里最快的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM