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.