mutable list iterators - a proposal

Raymond Hettinger python at rcn.com
Wed Mar 17 05:42:56 EST 2004


[Jess Austin]
> hi Terry,
> 
> Thanks for your thoughtful response.  I've tried to address the points
> you made, but I could have missed something.  b-)

List iterators likely won't change because
* it does not encourage an error prone programming style
* it is documented to perform as it currently does
* there is likely existing code that relies on the current behavior
* there are performance issues which changing it
* there do not seem to be compelling, general use cases to warrant a
change

Also, I'm not sure your proposal is self-consistent.  If I read it
correctly, there is a strong notion of having the iterator remember
the last item emitted even if its position changes.  However, with a
combination of slice deletion and insertion, the notion of the last
item emitted becomes muddy:

lyst = range(10)
it = iter(lyst)
for i in xrange(5):
   it.next()
lyst[3:7] = [20]
print it.next()          # Should this print 20 or 7 ?



 
> All of your suggestions are valid ways to deal with the current
> system, by deliberately building more machinery on top of it.  But
> none of them allow me to simply code a loop that assumes it will get
> the item that is now after the last one it got, even if it may have
> made changes to the list in the interim.  The class I posted does
> allow that.

Py2.4 adds a new type, collections.deque(), that can reasonably be
made to do what your asking (workable because there is no slicing,
just appending or popping from either end and setitem value
mutations):

>>> from collections import deque
>>> d = deque('abcdefg')
>>> it = iter(d)
>>> it.next()
'a'
>>> it.next()
'b'
>>> d.extend('hijk')
>>> d.appendleft('z')
>>> d.appendleft('y')
>>> list(it)   # this picks up right where it left off
['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
>>> d
deque(['y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k'])



Raymond Hettinger



More information about the Python-list mailing list