An exception occurs when an element is changed during dictionary traversal in Python.

Source: Internet
Author: User
This article describes how to solve errors caused by changing elements during dictionary traversal in Python. it discusses and solves the problem of dictionarychangedsizeduringiteration after adding or deleting elements, for more information about how to traverse the dictionary in Python, see:

Script:

#!/usr/bin/python dict={"a":"apple","b":"banana","o":"orange"}  print "##########dict######################" for i in dict:     print "dict[%s]=" % i,dict[i]  print "###########items#####################" for (k,v) in dict.items():     print "dict[%s]=" % k,v  print "###########iteritems#################" for k,v in dict.iteritems():     print "dict[%s]=" % k,v  print "###########iterkeys,itervalues#######" for k,v in zip(dict.iterkeys(),dict.itervalues()):     print "dict[%s]=" % k,v

Execution result:

##########dict###################### dict[a]= apple dict[b]= banana dict[o]= orange ###########items##################### dict[a]= apple dict[b]= banana dict[o]= orange ###########iteritems################# dict[a]= apple dict[b]= banana dict[o]= orange ###########iterkeys,itervalues####### dict[a]= apple dict[b]= banana dict[o]= orange

Well, then let's go to the "question "--

A piece of debate about Python dictionary traversal "....
Excerpt:

# Initialize a dict >>> d = {'a': 1, 'B': 0, 'C': 1, 'D ': 0} # The intention is to traverse dict. if the element value is 0, delete >>> for k in d :... if d [k] = 0 :... del (d [k])... traceback (most recent call last): File"
 
  
", Line 1, in
  
   
RuntimeError: dictionary changed size during iteration # An exception is thrown in the result. only one element of 0 is deleted. >>> D {'a': 1, 'C': 1, 'D': 0 >>>> d = {'a': 1, 'B': 0, 'C': 1, 'D': 0} # d. keys () is an array of the following objects> d. keys () ['A', 'C', 'B', 'D'] # This traversal is okay, because actually, the traversal here is d. the list constant keys (). >>> For k in d. keys ():... if d [k] = 0 :... del (d [k])...> d {'a': 1, 'C': 1} # The result is correct >>># initialize a dict >>>> d = {'a': 1, 'B': 0, 'C': 1, 'D': 0} # It is intended to traverse dict. if the element value is 0, delete> for k in d :... if d [k] = 0 :... del (d [k])... traceback (most recent call last): File"
   
    
", Line 1, in
    
     
RuntimeError: dictionary changed size during iteration # An exception is thrown in the result. only one element of 0 is deleted. >>> D {'a': 1, 'C': 1, 'D': 0 >>>> d = {'a': 1, 'B': 0, 'C': 1, 'D': 0} # d. keys () is an array of the following objects> d. keys () ['A', 'C', 'B', 'D'] # This traversal is okay, because actually, the traversal here is d. the list constant keys (). >>> For k in d. keys ():... if d [k] = 0 :... del (d [k])...> d {'a': 1, 'C': 1} # The result is also correct >>>
    
   
  
 

In fact, this problem is quite simple. that is to say, if a dictionary is traversed but it is changed in the traversal process, for example, adding or deleting an element will cause the traversal to exit, and throw a dictionary changed size during iteration exception.
The solution is to traverse the dictionary key value based on the dictionary key value, so that the traversal will not continue after the value is changed.
However, another great God throws a high theory:

First, we recommend that you use the iterator in the for k in adict format for python. Secondly, it is not recommended to delete the elements in the container in traversal. in libraries such as C ++ STL and Python, this situation often shows that your design scheme has problems, all have special requirements, corresponding to python, that is, to use adict. key () to make a copy. Finally, all Python containers do not promise thread security. to do this with multiple threads, you must lock it. This also shows that there is a problem with the business code design.

However, in the special case of "deleting a specific element in Traversal", it is concluded that "when traversing dict, we will develop the habit of using for k in d. keys ()". I think it is necessary to correct it. In normal traversal, for k in adict should be used.
In addition, pythonic uses adict = {k, v for adict. iteritems () if v! = 0} or alist = [I for I in alist if I! = 0]

This style makes me shine: how can I still use this syntax?
Take a closer look, he may mean:

#!/usr/bin/env python# -*- coding=utf-8 -*-a = {'a':1, 'b':0, 'c':1, 'd':0}b={}for k,v in a.items():  if v != 0:    b.update({k:v})adict = bdel bprint a#!/usr/bin/env python# -*- coding=utf-8 -*-a = {'a':1, 'b':0, 'c':1, 'd':0}b={}for k,v in a.items():  if v != 0:    b.update({k:v})adict = bdel bprint a

I don't know, right.
This was because I suddenly thought of the ternary operator at the beginning. I did not find it after a closer look. Previously, Goolge had a solution.

val = float(raw_input("Age: "))status = ("working","retired")[val>65]print "You should be",statusval = float(raw_input("Age: "))status = ("working","retired")[val>65]print "You should be",status

Val> 65 is a logical expression. The return value is 0 or 1, which is just used as the ID of the previous tuple. this is really amazing...
However, there is also a version in Google's documents.

#V1 if X else V2s = Nonea = "not null" if s == None else sprint a#'not null'

After I posted a post on the Chinese Python User Group (Chinese Python technical email list), many of my answers are as follows:

>>> alist = [1,2,0,3,0,4,5]>>> alist = [i for i in alist if i != 0]>>> alist[1, 2, 3, 4, 5]>>> d = {'a':1, 'b':0, 'c':1, 'd':0}>>> d = dict([(k,v) for k,v in d.iteritems() if v!=0])>>> d{'a':1,'c':1'}

If it is larger than Python> = 2.7
You can also use the following code:

>>> d = {k:v for k,v in d.iteritems() if v !=0 }


For more articles related to exceptions caused by changing elements in the dictionary traversal process in Python, refer to PHP!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.