繁体   English   中英

这两个字典语句在 for 循环中循环时是否相同?

[英]is these two dictonary statments are same while looping it in for loop?

我读到 my_dict.keys() 返回动态视图以遍历字典。 我通常在没有 keys() 函数的情况下迭代字典。

所以我的问题是,下面两个代码块是否相同? 如果不是,这两者有什么性能差异(哪个更优化)

# without keys() function
my_dict = {'key1' : 'value1',"key2" : "value2"}

for key in my_dict:
  print("current key is",key)
# withkeys() function
my_dict = {'key1' : 'value1',"key2" : "value2"}

for key in my_dict.keys():
  print("current key is",key)

注意:我通常使用python 3.7+版本,所以如果有任何版本方面的实现差异,请附上我可以参考的资源。

这两个代码块是相同的,唯一的区别是调用.keys()创建了一个临时的键视图对象,该对象几乎立即被丢弃(当开始for循环的对iter的隐式调用创建一个引用底层的dict_keyiterator对象时dict )。 创建键视图的成本非常小,因此对于大型dict来说,成本是无关紧要的。

证明它们相同(在 3.10.8 上运行):

>>> print(type(iter({})))
<class 'dict_keyiterator'>

>>> print(type(iter({}.keys())))
<class 'dict_keyiterator'>

在 Python 2 上,存在很大差异( .keys()会急切地将键浅层复制到新list ),但在 Python 3 中, .keys()只是浪费了少量固定的工作量,使键在前面显示,否则循环的其余部分行为和执行相同

听起来for key in my_dict稍微快一点......尝试:

from time import time

my_dict = {'key1' : 'value1',"key2" : "value2"}

start = time()
for _ in range(1000000):
    for key in my_dict:
      a = key
print(time() - start)


my_dict = {'key1' : 'value1',"key2" : "value2"}

start = time()
for _ in range(1000000):
    for key in my_dict.keys():
      a = key
print(time() - start)

# 0.28826069831848145
# 0.3530569076538086

这是我所期望的,因为for key in my_dict.keys():涉及另一个方法调用。


编辑:正如@ShadowRanger 指出的那样,我似乎使用了一种粗略的方法( time.time() )进行测量。 查看他富有洞察力的回答和评论。 另外,对于引用过时的文档表示歉意。

更好的方法是使用timeit ,它会显示两种情况下的结果与@ShadowRanger 的回答中指出的几乎相同,从而证实了评论中的其他观察结果。

from timeit import repeat

repeat(setup="my_dict = {i : 'value' for i in range(1000)}", stmt="""
for _ in range(100):
    for key in my_dict.keys():
      a = key
""", number=1000
)

repeat(setup="my_dict = {i : 'value' for i in range(1000)}", stmt="""
for _ in range(100):
    for key in my_dict:
      a = key
""", number=1000
)

"""
[2.141656800000419,
 2.098019299999578,
 2.0064776999997775,
 1.9754404000004797,
 2.020252399999663]

[1.9935685999998896,
 2.021206500000517,
 2.028992300000027,
 2.026352799999586,
 2.0209632999994938]
"""

暂无
暂无

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

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