Unexpected Behavior Iterating over a Mutating Object

Steve Holden steve at holdenweb.com
Wed Sep 14 06:13:19 CEST 2005


Delaney, Timothy (Tim) wrote:
> Dave Hansen wrote:
> 
> 
>>Again, iterating over an item that is mutating seems like a Bad
>>Idea(tm) to me.
> 
> 
> Absolutely. It can be safe to do it, but only if the iterator in
> question supports it, and all modifications occur through the iterator
> (this is how Java does it). In a Python for loop, the actual iterator is
> never exposed in any case, so this is not possible - it's just like
> using the new Java foreach syntax: for (element : iterable), but more
> flexible.
> 
> 
>>But I was curious: is this the intended behavior, or
>>does this fall under what C programmers would call 'undefined
>>behavior.'
> 
> 
> It's intended. From the tutorial (section 4.2 - for statement):
> http://docs.python.org/tut/node6.html#SECTION006200000000000000000
> 
>     It is not safe to modify the sequence being iterated over in the
>     loop (this can only happen for mutable sequence types, such as
>     lists). If you need to modify the list you are iterating over
>     (for example, to duplicate selected items) you must iterate over
>     a copy. The slice notation makes this particularly convenient: 
> 
>         >>> for x in a[:]: # make a slice copy of the entire list
>         ...    if len(x) > 6: a.insert(0, x)
>         ... 
>         >>> a
>         ['defenestrate', 'cat', 'window', 'defenestrate']
> 
> 
> Tim Delaney

I should have thought nowadays

     for x in tuple(a):
         ...

would have been slightly more acceptable, but I'm not the ultimate 
arbiter of style.

regards
  Steve
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC             http://www.holdenweb.com/




More information about the Python-list mailing list