newbie : removing recurring element from lists

Alex Martelli aleax at aleax.it
Fri Oct 11 12:08:31 CEST 2002


<posted & mailed>

CARbomboniere spa wrote:

> Hi,
> 
> How can I remove all occurences of a given value from a list ?
> E.g. : I have a list like :
> 
> a = [1,4,5,1,3,1,5,1,1,6]
> 
> And I want to remove all the 1 values; so the output should be :
> 
> a = [4,5,3,5,6]

Simplest is a list-comprehension:

  a[:] = [item for item in a if item != 1]



> I tried the following two ways, neither of which works as expected :
> 
> -----------------------------------
> # first way
> a = [1,4,5,1,3,1,5,1,1,6]
> 
> x = 0
> for t in a :
>     if t == 1 :
>         del a[x]
>     x = x + 1
> 
> print a

Don't alter the list you're looping on -- the results are often
confusing when you do.  If you DO want to use this complicated
approach, you need to loop on a COPY of the list, e.g. use:

for t in a[:]:

as the for-statement.  But the list-comprehension is better.


> # second way
> a = [1,4,5,1,3,1,5,1,1,6]
> 
> for t in a :
>     if t == 1 :
>         a.pop(t)
> 
> print a

Method pop takes as its argument an INDEX, not the value of
an item -- this snippet is therefore quite a bit buggier
than the previous one.  But again, the list comprehension
is simpler than fixing this.

The difference between a.pop(x) and del a[x] is that the
former is a function and returns the original value of
a[x], while the latter is a statement.  Here, you use
neither of these characteristics, so a working snippet
using pop rather than del would be basically identical to
the one I fixed above, just a wee bit slower (not enough
to make a difference anyway).


If you DO want to alter the original list element by element
AND can't use a list comprehension (or an equivalent loop
building a new list to replace the contents of the original
one), best might be to loop on indices -- either in reverse,
or with some care:

for x in range(len(a), -1, -1)
    if a[x] == 1: del a[x]

or

x = 0
while x<len(a):
    if a[x] == 1: del a[x]
    else: x = x+1

but I would NOT recommend this anyway -- the list comprehension
is going to work in a time roughly proportional to the number
of items in list a, while these approaches may take up to a
time proportional to the SQUARE of the number of items, if the
value you're trying to remove occurs often enough, particularly
towards the beginning of the list.


Alex




More information about the Python-list mailing list