Unexpected Behavior Iterating over a Mutating Object

Raymond Hettinger python at rcn.com
Tue Sep 13 19:42:39 EDT 2005


[Dave Hansen]
> It seems when an item is 'remove'd from data, the rest of the list
> 'shifts' over one, so what was 'next' now occupies the slot of the
> 'remove'd item.  When the next 'item' is selected from 'data', the
> _desired_ 'next' item is skipped.  So when 'data' has several
> consecutive items to be deleted, only every other one is 'remove'd.

Your analysis is dead-on.  Instead of being the "desired" item, the
iterator fetches a[0], a[1], a[2], ... as determined by the state of
the list when the index is retrieved.



> Again, iterating over an item that is mutating seems like a Bad
> Idea(tm) to me.

Right.


>  But I was curious: is this the intended behavior, or
> does this fall under what C programmers would call 'undefined
> behavior.'

It is intended.  The behavior is defined as above (a series of indexed
lookups).

BTW, the usual ways to deal with this are to:
1. iterating from the right using:  for item in reversed(data)
2. making a copy of the original list before iterating
3. creating a new result list:  data = [x for x in data if 'DEL' not in
x]


Raymond




More information about the Python-list mailing list