[英]Why is list.remove faster than list comprehension?
我不喜歡以下從列表中刪除元素的方法:
try:
lst.remove(elt)
except ValueError:
pass
我知道在Python中使用try除了塊並且我實際上使用它們是可以的,但是在這種特殊情況下我希望有一個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中實現,解釋器在C代碼調用C函數( PyObject_RichCompareBool
)時調用魔術方法__eq__
開銷。
你可以在這里看到源代碼:
https://svn.python.org/projects/python/trunk/Objects/listobject.c
搜索listremove
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.