Python 中 del、remove 和 pop 之间的区别
- 2024-12-09 08:30:00
- admin 原创
- 161
问题描述:
在 Python 中,这三种从列表中删除元素的方法有什么区别?
a = [1, 2, 3]
a.remove(2)
a # [1, 3]
a = [1, 2, 3]
del a[1]
a # [1, 3]
a = [1, 2, 3]
a.pop(1) # 2
a # [1, 3]
解决方案 1:
从列表中删除元素的三种不同方法的效果:
remove
删除第一个匹配的值,而不是特定的索引:
>>> a = [0, 2, 3, 2]
>>> a.remove(2)
>>> a
[0, 3, 2]
del
删除特定索引处的项目:
>>> a = [9, 8, 7, 6]
>>> del a[1]
>>> a
[9, 7, 6]
并pop
删除特定索引处的项目并返回它。
>>> a = [4, 3, 5]
>>> a.pop(1)
3
>>> a
[4, 5]
它们的错误模式也不同:
>>> a = [4, 5, 6]
>>> a.remove(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>> del a[7]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> a.pop(7)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
解决方案 2:
使用del
按索引删除元素,pop()
如果需要返回值,则按索引删除元素,以及remove()
按值删除元素。最后一种需要搜索列表,ValueError
如果列表中没有出现这样的值,则引发。
i
从元素列表中删除索引时n
,这些方法的计算复杂度为
del O(n - i)
pop O(n - i)
remove O(n)
解决方案 3:
由于没有其他人提到它,请注意del
(与pop
)允许由于列表切片而删除一系列索引:
>>> lst = [3, 2, 2, 1]
>>> del lst[1:]
>>> lst
[3]
IndexError
如果索引不在列表中,这也可以避免出现这种情况:
>>> lst = [3, 2, 2, 1]
>>> del lst[10:]
>>> lst
[3, 2, 2, 1]
解决方案 4:
其他人已经回答得很好了。这是我的答案 :)
显然,pop
是唯一一个返回值的方法,也是remove
唯一一个搜索对象的方法,同时del
将其自身限制为简单的删除。
解决方案 5:
这里有很多很好的解释,但我会尽力简化更多。
在所有这些方法中,remove
&pop
是后缀,而 delete 是前缀。
remove()
:用于删除元素的第一次出现。 =>列表中
remove(n)
的第一次出现。n
>>> a = [0, 2, 3, 2, 1, 4, 6, 5, 7]
>>> a.remove(2) # where i = 2
>>> a
[0, 3, 2, 1, 4, 6, 5, 7]
pop()
:用于删除元素……
如果没有指定索引:
pop()
=> 从列表末尾
>>> a.pop()
>>> a
[0, 3, 2, 1, 4, 6, 5]
如果指定了索引:
pop(index)
=> 索引
>>> a.pop(2)
>>> a
[0, 3, 1, 4, 6, 5]
警告:前方有危险方法
del()
:这是一种前缀方法。
注意同一方法的两种不同语法:with[]
和 without。它具有以下功能:
删除索引
del a[index]
=> 用于通过索引和其关联值进行删除,就像 一样pop
。
>>> del a[1]
>>> a
[0, 1, 4, 6, 5]
删除范围内的值
[index_1:index_N]
:
del a[0:3]
=> 范围内的多个值。
>>> del a[0:3]
>>> a
[6, 5]
最后但同样重要的一点是,一次性删除整个列表。
del (a)
=> 如上所述。
>>> del (a)
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
希望这可以澄清这个困惑。
解决方案 6:
流行音乐
获取索引(如果给定,则取最后一个),删除该索引处的值,并返回值
消除
获取值,删除第一次出现的值,并且不返回任何内容
删除
获取索引,删除该索引处的值,并且不返回任何内容
解决方案 7:
不同数据结构上的任何操作/功能都是为特定操作定义的。这里以您的情况为例,即删除元素、删除、弹出和移除。(如果您考虑集合,则添加另一个操作 - 丢弃)其他令人困惑的情况是添加时。插入/附加。为了演示,让我们实现双端队列。双端队列是一种混合线性数据结构,您可以在其中从两端添加元素/删除元素。(后端和前端)
class Deque(object):
def __init__(self):
self.items=[]
def addFront(self,item):
return self.items.insert(0,item)
def addRear(self,item):
return self.items.append(item)
def deleteFront(self):
return self.items.pop(0)
def deleteRear(self):
return self.items.pop()
def returnAll(self):
return self.items[:]
在这里,查看操作:
def deleteFront(self):
return self.items.pop(0)
def deleteRear(self):
return self.items.pop()
操作必须返回某些内容。因此,pop - 带或不带索引。如果我不想返回值:del self.items[0]
按值删除,而不是按索引删除:
消除 :
list_ez=[1,2,3,4,5,6,7,8]
for i in list_ez:
if i%2==0:
list_ez.remove(i)
print list_ez
返回 [1,3,5,7]
让我们考虑集合的情况。
set_ez=set_ez=set(range(10))
set_ez.remove(11)
# Gives Key Value Error.
##KeyError: 11
set_ez.discard(11)
# Does Not return any errors.
解决方案 8:
列表上的删除操作被赋予要删除的值。它会搜索列表以查找具有该值的项目,并删除找到的第一个匹配的项目。如果没有匹配的项目,则会出错,引发ValueError。
>>> x = [1, 0, 0, 0, 3, 4, 5]
>>> x.remove(4)
>>> x
[1, 0, 0, 0, 3, 5]
>>> del x[7]
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
del x[7]
IndexError: list assignment index out of range
del语句可用于删除整个列表。如果您将特定列表项作为 del 的参数(例如 listname[7] 专门引用列表中的第 8 项),它只会删除该项目。甚至可以从列表中删除“片段”。如果索引超出范围,则会引发错误,引发IndexError。
>>> x = [1, 2, 3, 4]
>>> del x[3]
>>> x
[1, 2, 3]
>>> del x[4]
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
del x[4]
IndexError: list assignment index out of range
pop的通常用法是从列表中删除最后一个项目,因为您将列表用作堆栈。与 del 不同,pop 返回从列表中弹出的值。您可以选择为 pop 指定索引值,并从列表末尾以外的位置弹出(例如 listname.pop(0) 将从列表中删除第一个项目并返回该第一个项目作为其结果)。您可以使用它使列表像队列一样运行,但是有一些库例程可以提供比 pop(0) 性能更好的队列操作。如果索引超出范围,则会引发错误,引发IndexError。
>>> x = [1, 2, 3]
>>> x.pop(2)
3
>>> x
[1, 2]
>>> x.pop(4)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
x.pop(4)
IndexError: pop index out of range
查看collections.deque以了解更多详细信息。
解决方案 9:
这里有一个详细的答案。
del 可用于任何类对象,而 pop 和 remove 则限于特定的类。
为了del
以下是一些示例
>>> a = 5
>>> b = "this is string"
>>> c = 1.432
>>> d = myClass()
>>> del c
>>> del a, b, d # we can use comma separated objects
我们可以__del__
在用户创建的类中重写方法。
具体用途见列表
>>> a = [1, 4, 2, 4, 12, 3, 0]
>>> del a[4]
>>> a
[1, 4, 2, 4, 3, 0]
>>> del a[1: 3] # we can also use slicing for deleting range of indices
>>> a
[1, 4, 3, 0]
为了pop
pop
将索引作为参数并删除该索引处的元素
不同之处在于del
,pop
当调用列表对象时,将返回该索引处的值
>>> a = [1, 5, 3, 4, 7, 8]
>>> a.pop(3) # Will return the value at index 3
4
>>> a
[1, 5, 3, 7, 8]
为了remove
remove 接受参数值并从列表中删除该值。
如果存在多个值,将删除第一个值
Note
:如果该值不存在,则会抛出 ValueError
>>> a = [1, 5, 3, 4, 2, 7, 5]
>>> a.remove(5) # removes first occurence of 5
>>> a
[1, 3, 4, 2, 7, 5]
>>> a.remove(5)
>>> a
[1, 3, 4, 2, 7]
希望这个答案对您有帮助。
解决方案 10:
删除基本上是针对值进行的。删除和弹出是针对索引进行的
Remove 基本上是删除第一个匹配的值。Delete 会从特定索引中删除项目。Pop 基本上是获取索引并返回该索引处的值。下次打印列表时,该值不会出现。
解决方案 11:
remove()、del 和 pop() 很慢……那么‘None’呢?
在这么多的回复中,我没有看到任何人谈论性能。所以我有一个性能提示:
删除后,remove()、del 和 pop() 将所有剩余的值移至左侧……
1, 2, 3, 4, 5, 6
remove(3)
1, 2, <- 4, 5, 6
...使得处理变得缓慢!
将所需值更改为空值以便进一步处理删除操作可以大大提高程序的速度,尤其是在处理大量数据时:
my_array[2] = None
当然,设置空值与删除空值是不同的,但如果你想更多地了解删除,思考这个操作的性能对我来说也很有趣。
解决方案 12:
虽然 pop 和 delete 都使用索引来删除元素,如上述注释中所述。一个关键区别是它们的时间复杂度。没有索引的 pop() 的时间复杂度为 O(1),但删除最后一个元素的情况则不同。
如果您的用例始终是删除最后一个元素,则最好使用 pop() 而不是 delete()。有关时间复杂度的更多解释,您可以参考https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
解决方案 13:
del、pop 和 remove 在执行速度方面的区别:
移除任何中间物品时:
import timeit
print(timeit.timeit("a=[1,2,3,4,5]
del a[3]",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]
a.pop(3)",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]
a.remove(3)",number=100000))
del
对比pop
对比remove
:
0.019387657986953855
0.02506213402375579
0.033232167130336165
del() 似乎比其他两个快得多,而 remove() 是最慢的。
删除最后一个项目时:
print(timeit.timeit("a=[1,2,3,4,5]
del a[-1]",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]
a.pop()",number=100000))
print(timeit.timeit("a=[1,2,3,4,5]
a.remove(5)",number=100000))
del
对比pop
对比remove
:
0.01974551402963698
0.020333584863692522
0.03434014297090471
del() 和 pop() 删除最后一项所花的时间相似。
解决方案 14:
这三种方法有什么区别吗?
用例不同。这里有几个例子。
由于
pop()
返回已移除的项目,因此如果返回值很重要,它很有用。例如,它可用于使用列表的索引列表将列表“拆分”为两个(有点像集合差)。但是,由于pop()
会更改列表,请确保索引列表按降序排序(以便从后面移除项目不会影响前面项目的索引)。示例:
lst = [1, 1, 2, 30, 40, 3, 2]
new_lst_idx = [4, 3, 0] # sorted in descending order
new_lst = [lst.pop(i) for i in new_lst_idx] # [40, 30, 1]
lst # [1, 2, 3, 2]
del
删除对 Python 对象的引用,因此正如其他答案所提到的,可以一次性删除列表的一个切片,这比逐个删除项目要快得多。事实上,如果我们执行 timeit 测试,删除切片所花的时间与删除一个项目所花的时间相同。
import timeit
setup = """
def del_slice(lst):
del lst[-100:]
def del_item(lst):
del lst[-100]
lst = list(range(10000))
"""
t1 = min(timeit.repeat("del_slice(lst.copy())", setup, number=1000)) # 0.043364200013456866
t2 = min(timeit.repeat("del_item(lst.copy())", setup, number=1000)) # 0.04249859999981709
remove()
根据值删除一个项目,因此它可以用于过滤值,但是速度太慢,所以最好使用替代方法,例如列表理解。
正如Sven Marnach 的回答所暗示的那样,如果你从列表的开头删除项目,这三种方法的效果都一样(不过,如果这是经常需要做的事情,那么这collections.deque
可能是更好的数据结构)。下面显示,如果从列表中删除第一个项目,这三种方法实际上没有区别。
setup = "lst = list(range(10000))"
t1 = min(timeit.repeat("lst.pop(0)", setup, number=10000)) # 0.019651099981274456
t2 = min(timeit.repeat("del lst[0]", setup, number=10000)) # 0.015160200011450797
t3 = min(timeit.repeat("lst.remove(lst[0])", setup, number=10000)) # 0.01593300001695752
解决方案 15:
您还可以使用 remove 通过索引删除值。
n = [1, 3, 5]
n.remove(n[1])
n 将引用 [1, 5]