[Python-Dev] a feature i'd like to see in python #1: better iteration control

Ben Wing ben at 666.com
Mon Dec 4 03:35:58 CET 2006



Brian Harring wrote:
> On Sun, Dec 03, 2006 at 06:24:17AM -0600, Ben Wing wrote:
>   
>> many times writing somewhat complex loops over lists i've found the need
>> to sometimes delete an item from the list.  currently there's no easy
>> way to do so; basically, you have to write something like
>>
>> i = 0
>> while i < len(list):
>>   el =  list[i]
>>   ...do something...
>>   if el should be deleted:
>>     del list[i]
>>   else:
>>     i += 1
>>
>> note that you can't write
>>
>> for x in list:
>>
>> or even
>>
>> for i in xrange(len(list)):
>>
>> note also that you need to do some trickiness to adjust the index
>> appropriately when deleting.
>>
>> i'd much rather see something like:
>>
>> for x:iter in list:
>>   ...do something...
>>   if x should be deleted:
>>     iter.delete()
>>
>> the idea is that you have a way of retrieving both the element itself
>> and the iterator for the element, so that you can then call methods on
>> the iterator.  it shouldn't be too hard to implement iter.delete(), as 
>> well as iter.insert() and similar functions. (the recent changes to the 
>> generator protocol in 2.5 might help.)
>>
>> the only question then is how to access the iterator.  the syntax i've 
>> proposed, with `x:iter', seems fairly logical (note that parallels with 
>> slice notation, which also uses a colon) and doesn't introduce any new 
>> operators. (comma is impossible since `for x,iter in list:' already has 
>> a meaning)
>>
>> btw someone is probably going to come out and say "why don't you just 
>> use a list comprehension with an `if' clause?  the problems are [1] i'd
>> like this to be destructive; 
>>     
>
> Just use slice assignment.
>
> l = list(xrange(100))
> l2 = [x for x in l if x > 50]
> l[:] = l2[:]
>
>   
>> [2] i'd like this to work over non-lists as well, e.g. hash-tables; 
>>     
>
> There in is the sucky part; iterator protocol is simple; what you're 
> proposing is extending iterators so that they recall the last value 
> (else iter.delete() would not do anything), which... eh.
>
> Think it sucks, to say the least ;)
>
> Simple example of where this gets ugly is in iterating over a file.
>
>   
with some more thought i see that a language extension to `for' isn't 
needed, as you can write something like

it = iter(foo)
for x in it:
  ...

but i still don't see why supporting iter.delete() is so wrong.  clearly 
it doesn't need to work on files or other such things where it doesn't 
make sense.

before you diss this completely, note that java supports exactly the 
same thing:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html


      remove

public void *remove*()

    Removes from the underlying collection the last element returned by
    the iterator (optional operation). This method can be called only
    once per call to next. The behavior of an iterator is unspecified if
    the underlying collection is modified while the iteration is in
    progress in any way other than by calling this method. 

    *Throws:*
        |UnsupportedOperationException
        <../../java/lang/UnsupportedOperationException.html>| - if the
        remove operation is not supported by this Iterator. 
        |IllegalStateException
        <../../java/lang/IllegalStateException.html>| - if the next
        method has not yet been called, or the remove method has already
        been called after the last call to the next method.




More information about the Python-Dev mailing list