Why is list.remove faster than list comprehension?

I don't like the following way to remove an item from a list:

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

      

I know it is possible to use try other than blocks in Python, and I do use them, but in this particular case I need a method list.remove_if_exists(elt)

where I really don't need to handle the case where the item 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? And how can I remove an item from a list, whether it is or not, in an elegant and efficient way?

Edit: People have pointed out that the reason is that it list.remove

stops looking for an element and the list comprehension goes through all the elements, so it should be slower.

So, I tried to remove the last item 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 list.remove

even faster than list comprehension? About twice as fast.

PS: I still like suggestions for elegant and efficient ways to remove an item in a list without caring about its actual membership.

+3


source to share


1 answer


As pointed out in the comments, your list comprehension O(n)

regardless of the contents of the list, but remove

will iterate over the list until the first element appears, and then breaks. It depends on the position of the element you want to remove.

The second reason, which is remove

much faster, is because it is implemented in C, the interpreter has the overhead of calling the magic method __eq__

while the C code calls the C ( PyObject_RichCompareBool

) function .

You can see the source code here:



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

Search listremove

+4


source







All Articles