python - 为什么 list.remove 比列表理解更快?

标签 python python-2.7

我不喜欢以下从列表中删除元素的方式:

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

我知道在 Python 中使用 try except block 是可以的,而且我实际上使用了它们,但在这种特殊情况下,我希望在我不使用时有一个 list.remove_if_exists(elt) 方法确实需要处理元素不在列表中的情况。

为了让事情更清楚,我尝试使用列表理解:

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

然而,这会变慢:

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

这是为什么呢?以及如何以一种优雅高效的方式从列表中删除一个项目,无论它是否存在?

编辑:人们提到原因是 list.remove 在找到元素时停止并且列表理解遍历所有元素,因此,它应该更慢。

所以我尝试删除列表中的最后一个元素 elt = lst[-1],以便两个进程都到达列表的最后:

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

为什么 list.remove 仍然比列表理解更快?大约快两倍。

PS:我仍然很乐意就在不关心其实际成员资格的情况下删除列表中的元素的优雅而有效的方法提出建议。

最佳答案

如评论中所述,无论列表的内容是什么,您的列表理解都是 O(n),而 remove 将遍历列表直到第一个元素存在,然后将中断。所以这取决于您要删除的元素的位置。

remove 快得多的第二个原因是它是用 C 实现的,解释器有调用魔术方法 __eq__ 的开销,而 C 代码调用 C函数(PyObject_RichCompareBool)。

你可以在这里看到源代码:

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

搜索 listremove

关于python - 为什么 list.remove 比列表理解更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43911107/

相关文章:

python - Django - 导入错误 : No module named apps

java - 语言操作工具

python - 如何在 Python 中捕获和处理来自另一个应用程序的实时事件?

python - 迷惑Gothon练习游戏Python

python - 一个函数,将函数应用于列表

python - 与版本无关的检查变量是否为整数?

Python subprocess.Popen 管道 IO 意外阻塞

python - pd.series.str.pad() 返回 NaN

python-2.7 - 如果相同的文件名已存在,则移动并替换?

python - 从 .asc 文件中删除最后 n 行并使用 matplotlib 进行绘图