Simple newbie question

Duncan Booth duncan at NOSPAMrcp.co.uk
Thu Dec 4 16:50:45 CET 2003


Angelo Secchi <secchi at sssup.it> wrote in 
news:mailman.107.1070547952.16879.python-list at python.org:

> The code i'm using is the following:
> 
> for line in lista:
>      if sum(line == 0) > 0:
>      lista.remove(line)
> 
> 
> The problem is that the loop stops at the first line with zeros and it
> doesn't remove the other lines with zeros (at least if I do not re-run
> the loop). Probably I do not understand how the loop works.

The loop will assign the first element of lista to line, then the second, 
then the third, and so on.

The problem is that, if you remove an element everything after it shifts up 
one place. Say you are looking at the first element and remove it, what was 
the second element now becomes the first element, but the next time round 
the loop you will look at the new second element and the one that was 
originally second (and is now first) will be skipped.

The solution is never to work on the list you are modifying. Just make a 
copy of the list and iterate over the copy, that means you can safely 
modify the original. To copy a list, use the 'list' builtin.

    for line in list(lista):
        if condition:
            lista.remove(line)

Alternatively turn your brain around and instead of deleting specific 
elements from the list just build a new list with the elements you want to 
keep. In this case you could do that using a list comprehension:

   lista = [ line for line in lista if not condition ]

(Obviously in both these cases replace condition with the correct 
expression, which as Gerhard pointed out may not be the condition in your 
original posting.)

The list comprehension rebinds the lista variable, whereas your original 
attempt was modifying the list inplace. This might be significant if there 
are other references to the same list elsewhere in your code. If it does 
matter, then you can still use a list comprehension to mutate the original 
list:

   lista[:] = [ line for line in lista if not condition ]

Unlike the original 'for' loop, this works by building a complete 
replacement list then mutating the original list in one go.
 
-- 
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