简体   繁体   中英

Why is list.remove faster than list comprehension?

I am not fond of the following way of removing an element from a list:

try:
    lst.remove(elt)
except ValueError:
    pass

I know it is ok to use try except blocks in Python and I actually use them, but in this particular case I wish there was a list.remove_if_exists(elt) method when I don't really need to handle the case when the element is not in the list.

To make things clearer I tried using a list comprehension:

lst = [x for x in lst if x != elt]

However, this turned out to be slower:

In [3]: %timeit [x for x in lst if x != elt]
1000 loops, best of 3: 334 µs per loop

In [4]: %timeit lst[:].remove(elt)
10000 loops, best of 3: 42.8 µs per loop

Why is that? And how can I remove an item from a list whether it exists or not in an elegant and efficient way?

Edit: people mentioned the reason is that list.remove stops when finding the element and the list comprehension goes through all elements, therefore, it should be slower.

So I tried removing the last element in the list, elt = lst[-1] , so that both processes reach the very end of the list:

In [7]: %timeit [x for x in lst if x != elt]
1000 loops, best of 3: 343 µs per loop

In [8]: %timeit lst[:].remove(elt)
10000 loops, best of 3: 143 µs per loop

Why is list.remove still faster than the list comprehension? About twice as fast.

PS: I'd still love to suggestions for elegant and efficient ways of removing an element in a list without caring about its actual membership.

As mentioned in the comments, your list comprehension is O(n) no matter what the content of the list, while remove will iterate over the list until the first element is present and then will break. So this depends on the position of the element you want to remove.

A second reason that the remove is much faster is that it's implemented in C, the interpreter has overhead of calling the magic method __eq__ while the C code calls a C function ( PyObject_RichCompareBool ).

You can see the source code here:

https://svn.python.org/projects/python/trunk/Objects/listobject.c

Search for listremove

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM