Confused over Lists

Duncan Booth duncan at NOSPAMrcp.co.uk
Fri Aug 2 10:43:05 EDT 2002


"Paul Brian" <paul1brian at yahoo.com> wrote in
news:1028296609.5721.0.nnrp-12.c1c3e11b at news.demon.co.uk: 

> the following I thought should work :-
> 
> demoList = [1, 1, 2, 3, 4, 5]
> for num in demoList:
>     if num == 1:
>         demoList.remove(num)
> print demoList
> 
> but I get
>>>> [1, 2, 3, 4, 5]
> 
> 1) Am I missing something really obvious on how to handle this the way
> I think it *should* work (NB absolutley no PEP orientated issues here
> - no desire to try and say we should change behaviour of lists cos i
> dont get it) 

Copy the list before you iterate over it if you are going to either insert 
or remove items from the list. Making a copy of a list is generally pretty 
fast and just requires a 3 character change to what you have:

    demoList = [1, 1, 2, 3, 4, 5]
    for num in demoList[:]:
        if num == 1:
            demoList.remove(num)
    print demoList

Alternatively in this case you might like to use a while loop:

    while 1 in demoList:
        demoList.remove(1)

Or a list comprehension:

    demoList = [ num for num in demoList if num != 1 ] 

or even a filter:

    demoList = filter(lambda num: num != 1, demoList)

> 
> 2) How do I get access to that magic counter. It would be very useful
> in all sorts of ways.

Sorry, you don't. In this particular case, when you are iterating over a 
list, there is indeed a magic counter, but the for loop in general doesn't 
use a counter. It creates an iterator and sometimes iterators are 
implemented using counters, but often they aren't.

Or to put it another way, you can use a for loop to iterate over the 
elements of objects that you cannot subscript:

    f = file('something')
    for line in f:
        dosomething()

but no way can you refer to f[93].

A future version of Python will include a new builtin called enumerate 
that does roughly what you want, so you can define your own function now 
and use it:

    from __future__ import generators
    def enumerate(collection):
        'Generates an indexed series:  (0,coll[0]), (1,coll[1]) ...'     
        i = 0
        it = iter(collection)
        while 1:
            yield (i, it.next())
            i += 1

    # Now you can do:
    demoList = [1, 1, 2, 3, 4, 5]
    for index, num in enumerate(demoList):
        print index, num


-- 
Duncan Booth                                             duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



More information about the Python-list mailing list