我不喜欢以下从列表中移除元素的方式:
try:
lst.remove(elt)
except ValueError:
pass
我知道在Python中使用 try except 块是可以的,而且我实际上也使用它们,但在这种特定情况下,我希望有一个 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
的速度仍然比列表推导式快?大约快两倍。
附注:我仍然希望得到有关优雅和高效地从列表中删除元素而不关心其实际成员资格的建议。
remove
只会移除第一个匹配的元素。而你的comprehension
会移除所有匹配的元素。(这并不一定解释了性能问题,只是有一点点的区别。) - Alex Rileyfilter(function, iterable)
:) - Take_Care_lst = [1, 2, 3, 4, 5]
并移除5
。remove
仍然稍微快一些,但最慢和最快运行之间的差异非常有趣。 - zipa