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.po...

问题描述:

在 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:

其他人已经回答得很好了。这是我的答案 :)

移除 vs 弹出 vs 删除

显然,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将索引作为参数并删除该索引处的元素

不同之处在于delpop当调用列表对象时,将返回该索引处的值

>>> 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]

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用