Workarounds for changing element-causing exceptions in Python during traversal of a dictionary

Source: Internet
Author: User
Let's take a look at some of the basic ways that you can iterate through a dictionary in Python:
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.item S ():     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 D ict[o]= Orange ########## #iterkeys, itervalues####### dict[a]= apple dict[b]= Banana dict[o]= Orange

Well, then we went to "the point"--

A "controversy" over the traversal of a python dictionary ....
First excerpt:

#这里初始化一个dict >>> d = {' A ': 1, ' B ': 0, ' C ': 1, ' d ': 0} #本意是遍历dict, the value of the found element is 0, delete >>> for k in D: ... if d[k] = = 0: ... del (d[k]) ... Traceback (most recent): File "
 
  ", line 1, in
  
   
Runtimeerror:dictionary changed size during iteration# The result throws an exception, two elements of 0, also only delete one. >>> d{' A ': 1, ' C ': 1, ' d ': 0}>>> d = {' A ': 1, ' B ': 0, ' C ': 1, ' d ': 0} #d. Keys () is an array of subscripts >>> D.keys () [' A ', ' C ', ' B ', ' d '] #这样遍历, no problem, because actually this is the D.keys () this list constant. >>> for K in D.keys (): ... if d[k] = = 0: ... del (d[k]) ...>>> d{' A ': 1, ' C ': 1} #结果也是对的 >>> #这里初始化   A dict>>> D = {' A ': 1, ' B ': 0, ' C ': 1, ' d ': 0} #本意是遍历dict, the value of the found element is 0, delete >>> for k in D: ... if d[k] = = 0: ... Del (D[k]) ... Traceback (most recent): File "
   
    
     ", line 1, in 
     
      runtimeerror:dictionary changed size during iteration# The result throws an exception, two 0 elements, also only delete one. >>> d{' A ': 1, ' C ': 1, ' d ': 0} >>> D = {' A ': 1, ' B ': 0, ' C ': 1, ' d ': 0} #d. Keys () is an array of subscripts >>> D.keys ( [' A ', ' C ', ' B ', ' d '] #这样遍历, no problem, because actually this is the D.keys () this list constant. >>> for K in D.keys (): ... if d[k] = = 0: ... del (d[k]) ...>>> d{' A ': 1, ' C ': 1} #结果也是对的 >>> 
     

    
   
  
 

In fact, this problem is very simple, that is, if you traverse a dictionary, but change him in the traversal, such as adding or deleting an element, will cause the traversal to exit, and throw a dictionary changed size during iteration exception.
The workaround is to traverse the dictionary key value, which is based on the dictionary key value, so that changing the value will not affect traversal continuation.
But here is another great God who throws pontificate:

First, Python is the recommended use of iterators, that is, the for-K in adict form. Second, it is not recommended to delete the elements in the container in the traversal, in libraries such as C + + STL and Python, because it often indicates that there is a problem with your design and that all have special requirements that correspond to Python, which is to use Adict.key () to make a copy. Finally, all of the Python containers are not committed to thread safety, and you have to do this with multiple threads, which in itself has to be locked, which also illustrates the problem with the business code design.

But by the exception of "delete specific elements in traversal", it is concluded that "when traversing dict, develop the habit of using for K in D.keys", I think it is necessary to rectify it. In normal traversal, you should use the for K in Adict.
In addition, for the "delete element in traversal" requirement, the pythonic approach is adict = {k, V for Adict.iteritems () if V! = 0} or alist = [i-I in alist if I! = 0]

This is the way I see it: How do you get this grammar?
A closer look, he may have meant:

#!/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 I n A.items ():  if V! = 0:    b.update ({k:v}) Adict = Bdel Bprint A

I don't know, right.
Because this writing began to make me suddenly think of the ternary operator, a careful look only to find not, before goolge to have 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, return 0 or 1, just as the ID of the previous tuple to take the value, it is really wonderful ...
But there's another version in Google's profile.

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

Later posts in the Python user group (Chinese Python Technical mailing list) mentioned after many of the great God answers are as follows:

>>> alist = [1,2,0,3,0,4,5]>>> Alist = [i-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 greater than python>=2.7
You can also use this notation:

>>> d = {k:v for k,v in D.iteritems () if v!=0}
  • 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.