Speno's Pythonic Avocado 24.5.2004

2004-05-24

The flowers are still standing! (abusing iterators)

A few months ago a friend and I were discussing a bug in dnspython when I first learned about the trouble of trying to delete items from a dictionary while iterating over that dictionary. If you try to do this, you'll get a RuntimeError exception explaining that 'dictionary changed size during iteration'. Try it yourself:

d = { 1: 'one', 2: 'two', 3: 'trois'} for key in d: del d[key]

I bring this up now because a similar issue came up recently and bit me. I was trying to enumerate a list and delete some of its elements. Python lets you do this without raising an exception, but it's probably not going to work the way you think it does.

>>> l = range(3) # take a little list >>> e = enumerate(l) # enumerate it >>> e.next() # ok (0, 0) >>> del l[0] # get rid of this element >>> e.next() # oops, we skipped one... (1, 2) >>> e.next() # The flowers are still standing! >>> e.next()Traceback (most recent call last): File "", line 1, in ? StopIteration

The list shrinks in place when you delete an element, but the index part of your iterator moves ahead and causes you to skip an element. In this case, we skip the element with the value of '1' because it resides at l[0] after the deletion.

So, if you wanted to do this properly, use range, start at the end of your list, and count backwards...

Take care.

This post references topics: python
posted at 23:03:28    #    comment []    trackback []
May 2004
MoTuWeThFrSaSu
      1 2
3 4 5 6 7 8 9
10111213141516
17181920212223
24252627282930
31      
Apr
2004
 Jun
2004

One python programmer's search for understanding and avocados. This isn't personal, only pythonic.

XML-Image Letterimage

© 2004-2005, John P. Speno