I read that my_dict.keys() returns the dynamic view to iterate over the dictionary. I usually iterate the dictionary without the keys() function.
So my question is, are below two code blokes are same? if not, what performance differences do these two have (which one is more optimized)
# 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)
Note: I usually use python version 3.7 so if there's any version-wise implementation difference, kindly attach resources that I can refer to.
CodePudding user response:
It sounds like for key in my_dict
is faster... try:
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
Which is what I'd expect because for key in my_dict.keys():
involves one more method call.
On larger dictionaries, the call to .keys()
might be slightly faster?
from time import time
my_dict = {}
for i in range(100000):
my_dict[i] = i
start = time()
for _ in range(10000):
for key in my_dict:
a = key
print(time() - start)
start = time()
for _ in range(10000):
for key in my_dict.keys():
a = key
print(time() - start)
# 38.963454723358154
# 38.85090208053589
CodePudding user response:
The two code blocks are the same, the only difference is that calling .keys()
creates a temporary keys view object that is thrown away almost immediately (when the implicit call to iter
that begins the for
loop creates a dict_keyiterator
object that references the underlying dict
). The cost of creating a keys view is pretty small, so for large dict
s, the cost is irrelevant.
Proving they're the same (run on 3.10.8):
>>> print(type(iter({})))
<class 'dict_keyiterator'>
>>> print(type(iter({}.keys())))
<class 'dict_keyiterator'>
On Python 2, there was a big difference (.keys()
would eagerly shallow copy the keys to a new list
), but in Python 3, .keys()
is just wasting a tiny fixed amount of work making the keys view up front, and otherwise the rest of the loop behaves & performs identically.