【问题标题】:Difference between del, remove, and pop on lists列表中删除、删除和弹出的区别
【发布时间】:2012-07-16 06:08:37
【问题描述】:
>>> 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]
>>> 

以上三种从列表中删除元素的方法有什么区别吗?

【问题讨论】:

标签: python list


【解决方案1】:

从列表中移除元素的三种不同方法的效果:

remove 删除 first 匹配 value,而不是特定索引:

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

【讨论】:

  • 我认为del 是类似于print 的python 2 语法保留,但它仍然适用于python 3。
  • @jxramos: del 不是语法保留,不是。语法不变,就像returnifwhile
  • 值得一提的是,用户在迭代列表并在迭代的同时在其上使用这些函数时应该小心。
  • @rite2hhh 它测试是否相等。平等测试首先测试身份作为优化
  • @rite2hhh:值相等包含在expression reference中。
【解决方案2】:

使用del按索引删除元素,pop()如果需要返回值则按索引删除,remove()按值删除元素。最后一个需要搜索列表,如果列表中没有出现这样的值,则引发ValueError

n 元素列表中删除索引i 时,这些方法的计算复杂度为

del     O(n - i)
pop     O(n - i)
remove  O(n)

【讨论】:

  • 是否弹出需要搜索列表
  • +1 表示复杂性分解。说明当元素位于列表末尾时,delete 和 pop 是如何保持不变的。
  • 记住伙计们......任何基于索引的都是一次O(n-1)......如果你必须进行查找(按值),它将遍历集合直到找到元素.
  • @PepitoFernandez 在 Python 中按索引查找列表是 O(1)。 (Python 中的列表类似于 C++ 中的向量。)
  • @PlasmaBinturong 您应该使用您认为更具可读性的内容,除非您有数据证明性能很重要。如果你有,你需要衡量在你的具体情况下什么更快。我的猜测也是 del 稍微快一点,但出于不同的原因:在 C 中实现的类型上查找 __delitem__ 是按索引而不是按名称发生的,而 pop 需要在整个过程中查找描述符协议。函数本身的执行应该花费相同的时间。两者都返回一个指针——一个指向被移除的对象,另一个指向None
【解决方案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 将自身限制为简单的删除。

    【讨论】:

    • 谢谢!注意:在python中,由于列表的实现方式(实际上是数组......!),“前进到那个节点位置”是O(1)
    【解决方案5】:

    这里有很多很好的解释,但我会尽力简化更多。

    在所有这些方法中,remove & pop后缀,而删除是前缀

    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():是前缀方法。

    注意同一方法的两种不同语法:使用[] 和不使用。它拥有以下能力:

    • 删除索引
      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
    

    希望这能澄清困惑。

    【讨论】:

    • postfixprefix 有什么区别?
    • 后缀删除功能:找到值并删除它。前缀去除功能:根据前缀去除
    【解决方案6】:

    流行音乐

    获取索引(如果给定,则获取最后一个),删除该索引处的值,并返回值

    移除

    取值,删除第一次出现,不返回任何内容

    删除

    获取索引,删除该索引处的值,并且不返回任何内容

    【讨论】:

    • pop 也从列表中删除值
    【解决方案7】:

    针对不同数据结构的任何操作/功能都是针对特定操作定义的。在您的情况下,即删除元素、删除、弹出和删除。 (如果您考虑集合,请添加另一个操作 - 丢弃) 其他令人困惑的情况是在添加时。插入/追加。 为了演示,让我们实现双端队列。 deque 是一种混合线性数据结构,你可以在其中添加元素/从两端删除元素。(后端和前端)

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

      这是一个详细的答案。

      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]
      

      希望这个答案有帮助。

      【讨论】:

        【解决方案9】:

        虽然 pop 和 delete 都使用索引来删除上面 cmets 中所述的元素。一个关键的区别是它们的时间复杂度。没有索引的 pop() 的时间复杂度是 O(1) 但删除最后一个元素的情况不同。

        如果您的用例总是要删除最后一个元素,则最好使用 pop() 而不是 delete()。关于时间复杂度的更多解释,可以参考https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt

        【讨论】:

        • 这在多个方面都是错误的。没有delete这样的方法。不同之处在于pop 返回值,而del 适用于切片。在 pop 有效的情况下,del 具有完全相同的计算复杂度(并且在常数项上稍快)。
        【解决方案10】:

        列表上的remove 操作被赋予一个要删除的值。它搜索列表以查找具有该值的项目并删除它找到的第一个匹配项目。如果没有匹配项,则为错误,引发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 和 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

        【讨论】:

          【解决方案11】:

          Remove 基本上适用于 value 。 删除和弹出索引上的工作

          Remove 基本上是删除第一个匹配的值。 删除从特定索引中删除项目 Pop 基本上采用一个索引并返回该索引处的值。下次打印列表时,值不会出现。

          【讨论】:

          • 虽然我们感谢您的回答,但如果它在其他答案之上提供额外的价值会更好。在这种情况下,您的答案不会提供额外的价值,因为其他用户涵盖了您在答案中包含的所有内容。作为次要问题,当您可以将其粘贴为文本时,请不要将文本包含为图片。如果之前的回答对您有帮助,您应该vote it up
          【解决方案12】:

          您也可以使用 remove 按索引删除值。

          n = [1, 3, 5]
          
          n.remove(n[1])
          

          n 将引用 [1, 5]

          【讨论】:

          • 尝试n = [5, 3, 5],然后尝试n.remove(n[2])
          • @abarnert 您的用例与以下情况同步工作 n = [5,3,5] ,然后是 n.remove(5)。这两个都从列表中删除第一个遇到的元素。
          • @AkhilGhatiki n.remove(n[2]) 删除 n[0],而不是 n[2]。所以这不仅仅是无缘无故的线性时间(当 N=3 时可能没什么大不了的),它也是错误的(不管 N 是多少都是大问题)
          猜你喜欢
          • 2015-04-22
          • 2019-02-20
          • 2010-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-18
          • 2014-05-10
          • 2010-09-13
          相关资源
          最近更新 更多