[英]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.