Python compares two ways of traversing the dictionary of dict

  • 2020-04-02 13:41:39
  • OfStack

Python has won over programmers with its elegant syntax and convenient built-in data structure.
One of the most useful data structures is the dict, which is very simple to use. When it comes to traversing a dict structure, I think most people think of the for key in dictobj method, and it works in most cases. But it's not completely safe. Here's an example:


# I'm going to initialize one here dict
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
# The idea is to traverse dict , the value of the found element is 0 If so, delete it 
>>> for k in d:
...   if d[k] == 0:
...     del(d[k])
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
# It throws an exception, two 0 I'm only going to delete one of them. 
>>> d
{'a': 1, 'c': 1, 'd': 0}

>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys()  It's an array of subscripts 
>>> d.keys()
['a', 'c', 'b', 'd']
# So we're going to walk through it, and we're going to be fine, because we're actually walking through it d.keys() this list Constants. 
>>> for k in d.keys():
...   if d[k] == 0:
...     del(d[k])
... 
>>> d
{'a': 1, 'c': 1}
# The result is also right 
>>>

Actually, I've simplified this example, and I found this problem in a multi-threaded program, so my advice is: get in the habit of using for k in d.eys () when traversing dict.
However, if it's multi-threaded, is that absolutely safe? Also not necessarily: when two threads are taken after the d.keeys (), if two threads are to delete the same key, the first delete will succeed, after the deletion of the KeyError, this seems to be only through other ways to ensure.


Another: performance comparison of two dict traversal methods

About the performance problem of tangling with and without brackets in dict traversal


for (d,x) in dict.items():
     print "key:"+d+",value:"+str(x)

for d,x in dict.items():
    print "key:"+d+",value:"+str(x)

Performance test results with and without brackets:


 The test results 
 Test article number :15
 Start time with parentheses :2012-06-14 12:13:37.375000
 Close bracket time :2012-06-14 12:13:37.375000
 The time interval :0:00:00
 Start time without parentheses :2012-06-14 12:13:37.375000
 End time without parentheses :2012-06-14 12:13:37.375000
 The time interval :0:00:00
 Test article number :50
 Start time with parentheses :2012-06-14 12:13:57.921000
 Close bracket time :2012-06-14 12:13:57.921000
 The time interval :0:00:00
 Start time without parentheses :2012-06-14 12:13:57.921000
 End time without parentheses :2012-06-14 12:13:57.937000
 The time interval :0:00:00.016000
 Test article number :100
 Start time with parentheses :2012-06-14 11:53:57.453000
 Close bracket time :2012-06-14 11:53:57.468000
 The time interval :0:00:00.015000
 Start time without parentheses :2012-06-14 11:53:57.468000
 End time without parentheses :2012-06-14 11:53:57.531000
 The time interval :0:00:00.063000
 Test article number :150
 Start time with parentheses :2012-06-14 12:00:54.812000
 Close bracket time :2012-06-14 12:00:54.828000
 The time interval :0:00:00.016000
 Start time without parentheses :2012-06-14 12:00:54.828000
 End time without parentheses :2012-06-14 12:00:54.921000
 The time interval :0:00:00.093000
 Test article number :200
 Start time with parentheses :2012-06-14 11:59:54.609000
 Close bracket time :2012-06-14 11:59:54.687000
 The time interval :0:00:00.078000
 Start time without parentheses :2012-06-14 11:59:54.687000
 End time without parentheses :2012-06-14 11:59:54.734000
 The time interval :0:00:00.047000
 Test article number :500
 Start time with parentheses :2012-06-14 11:54:39.906000
 Close bracket time :2012-06-14 11:54:40.078000
 The time interval :0:00:00.172000
 Start time without parentheses :2012-06-14 11:54:40.078000
 End time without parentheses :2012-06-14 11:54:40.125000
 The time interval :0:00:00.047000
 Test article number :1000
 Start time with parentheses :2012-06-14 11:54:49.171000
 Close bracket time :2012-06-14 11:54:49.437000
 The time interval :0:00:00.266000
 Start time without parentheses :2012-06-14 11:54:49.437000
 End time without parentheses :2012-06-14 11:54:49.609000
 The time interval :0:00:00.172000
 Test article number :2000
 Start time with parentheses :2012-06-14 11:54:58.921000
 Close bracket time :2012-06-14 11:54:59.328000
 The time interval :0:00:00.407000
 Start time without parentheses :2012-06-14 11:54:59.328000
 End time without parentheses :2012-06-14 11:54:59.687000
 The time interval :0:00:00.359000
 Test article number :5000
 Start time with parentheses :2012-06-14 11:55:05.781000
 Close bracket time :2012-06-14 11:55:06.734000
 The time interval :0:00:00.953000
 Start time without parentheses :2012-06-14 11:55:06.734000
 End time without parentheses :2012-06-14 11:55:07.609000
 The time interval :0:00:00.875000
 Test article number :10000
 Start time with parentheses :2012-06-14 11:55:15.656000
 Close bracket time :2012-06-14 11:55:17.390000
 The time interval :0:00:01.734000
 Start time without parentheses :2012-06-14 11:55:17.390000
 End time without parentheses :2012-06-14 11:55:19.109000
 The time interval :0:00:01.719000
 Test article number :20000
 Start time with parentheses :2012-06-14 12:19:14.921000
 Close bracket time :2012-06-14 12:19:18.593000
 The time interval :0:00:03.672000
 Start time without parentheses :2012-06-14 12:19:18.593000
 End time without parentheses :2012-06-14 12:19:22.218000
 The time interval :0:00:03.625000


We can see that the performance of the bracketed is higher when the number of dict bars is below 200, but the execution time without the bracketed will be less after the number of dict bars is above 200.

Here is the test code:


 test Code
#-*- coding: utf-8 -*-
import datetime,codecs
dict = {}
for i in xrange(0,20000):
    dict.setdefault("name"+str(i))
    dict["name"+str(i)]="name"
s=codecs.open(r'c:\dict.txt','a', 'utf-8')
def write(des):
    s.write(des.decode("utf-8"))
write(" Test article number :")
write(str(len(dict))+"rn")
write(" Start time with parentheses :")
a=datetime.datetime.now()
s.write(str(a)+"rn")
for (d,x) in dict.items():
    print "key:"+d+",value:"+str(x)
write(" Close bracket time :")
b=datetime.datetime.now()
write(str(b)+"rn")
write(" The time interval :")
write(str(b-a)+"rn")
write(" Start time without parentheses :")
c=datetime.datetime.now()
write(str(c)+"rn")
for d,x in dict.items():
    print "key:"+d+",value:"+str(x)
write(" End time without parentheses :")
d=datetime.datetime.now()
write(str(d)+"rn")
write(" The time interval :")
write(str(d-c)+"rn")
write("rn")
s.close()

Is there a good solution to the problem of Chinese garbled code... ?


Related articles: