[0, 0, 0, 1, 1, 1, 0] ... remove all 0 values

Stefan Behnel stefan_ml at behnel.de
Thu Jul 9 02:42:06 EDT 2009


Paul Rubin wrote:
> Daniel Austria writes:
>> just one question. How can i remove all 0 values in a list? 
> 
> I prefer:
> 
>    newlist = list(x for x in oldlist if x != 0)
> 
> to the square bracket list comprehension that a few people have
> suggested.  This is because in python 2.x, the listcomp "leaks" its
> index variable into the surrounding scope, but the generator
> expression above doesn't.

As you indicated, that's been fixed in Py3, though. So if your code works
in Py3.x, you can be somewhat sure that the leak doesn't have side effects.
Plus, it's pretty easy to ignore those leaks as long as you use a suitable
name for the loop variable.

Also note that the performance characteristics may not be identical in both
cases, depending on where you run your code. Cython, for example, will
write a list comprehension out as a rather straight C loop, but when we
implement generator expressions in Cython, it may have to get turned into a
generator function instead of a loop, so that you'd get a much larger
overhead than for the plain list comprehension (although in the simple case
above it would likely get optimised away).

CPython shows a similar difference:

$ python3.1 -m timeit '[x for x in range(1000) if x]'
10000 loops, best of 3: 170 usec per loop
$ python3.1 -m timeit -s 'r=[i%2 for i in range(2000)]' \
				'[x for x in r if x]'
1000 loops, best of 3: 222 usec per loop

$ python3.1 -m timeit 'list(x for x in range(1000) if x)'
1000 loops, best of 3: 227 usec per loop
$ python3.1 -m timeit -s 'r=[i%2 for i in range(2000)]' \
				'list(x for x in r if x)'
1000 loops, best of 3: 280 usec per loop


Not that I'd consider those numbers worth bothering...

Stefan



More information about the Python-list mailing list