【问题标题】:Function which removes the first item in a list (Python)删除列表中第一项的函数(Python)
【发布时间】:2016-03-10 20:10:36
【问题描述】:

我正在尝试编写一个函数来删除 Python 列表中的第一项。这是我尝试过的。当我调用函数时,为什么 remove_first_wrong 不改变 l ?当我在主函数中执行列表切片方法时,为什么它会起作用?

def remove_first_wrong(lst):
    lst = lst[1:]

def remove_first_right(lst):
    lst.pop(0)

if __name__ == '__main__':
    l = [1, 2, 3, 4, 5]
    remove_first_wrong(l)
    print(l)

    l_2 = [1, 2, 3, 4, 5]
    remove_first_right(l_2)
    print(l_2)

    # Why does this work and remove_first_wrong doesn't?
    l_3 = [1, 2, 3, 4, 5]
    l_3 = l_3[1:]
    print(l_3)

【问题讨论】:

  • @pigletfly:混入了一些名称与引用的混淆。
  • 最好是返回值而不是就地编码,它允许使用更少的临时变量来实现更多动态类型的短代码。

标签: python


【解决方案1】:

或者,您可以使用del关键字:

def remove_first_element(lst):
   del lst[0]
   return lst

【讨论】:

    【解决方案2】:

    在函数 remove_first_wrong 内部,= 符号将名称 lst 重新分配给右侧的对象。这是一个全新的对象,由切片操作lst[1:]创建。因此,分配给的对象lst 是该函数的本地对象(实际上它会在返回时消失)。

    这就是 Martijn 所说的“你然后反弹 lst(函数中的本地名称)以引用该新列表。”

    相反,lst.pop(0) 是对给定对象的调用——它对对象进行操作。

    例如,这也可以正常工作:

    def remove_first_right2(lst):
        x = lst  # x is assigned to the same object as lst
        x.pop(0) # pop the item from the object
    

    【讨论】:

      【解决方案3】:

      对列表进行切片会返回一个 new 列表对象,它是您在切片中指定的原始列表索引的副本。然后您重新绑定lst(函数中的本地名称)以引用该新列表。旧列表在该过程中永远不会改变。

      list.pop() 另一方面,对列表对象本身进行操作。您使用什么参考来到达列表并不重要。

      如果没有函数,你会看到同样的东西:

      >>> a = [1, 2]
      >>> b = a[:]  # slice with all the elements, produces a *copy*
      >>> b
      [1, 2]
      >>> a.pop()  # remove an element from a won't change b
      2
      >>> b
      [1, 2]
      >>> a
      [1]
      

      使用[:] 是制作列表浅表副本的两种方法之一,请参阅How to clone or copy a list?

      您可能想阅读或观看Ned Batchelder's Names and Values presestation,以进一步帮助了解 Python 名称和对象的工作原理。

      【讨论】:

        猜你喜欢
        • 2019-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-18
        • 2012-10-26
        • 1970-01-01
        • 2015-06-12
        • 2013-11-28
        相关资源
        最近更新 更多