【问题标题】:Python assign to slice vs remove from end? [duplicate]Python分配给切片vs从末尾删除? [复制]
【发布时间】:2021-03-10 04:31:34
【问题描述】:

假设我们要创建所有长度为 5 的列表,这些列表以 [0, -1] 开头并以 3 个全为 2 或 3 的整数结尾。一个这样的列表(8 个可能的列表)是[0, -1, 2, 2, 3]。这是一些简单的(错误的)递归代码:

def op(a):
    print(a)
    if(len(a) < 5):
        a.append(2)
        op(a)
        print("pre 2", a)
        a = a[:-1] #.pop()
        print("post 2", a)
    if(len(a) < 5):
        a.append(3)
        print("pre 3", a)
        op(a)
        print("post 3", a)
        a = a[:-1] #.pop()

op(a)
print(a)

但是,此代码不起作用并输出一些随机列表。但是,如果我们将行 a = a[:-1] 替换为 a.pop(),它就完全可以正常工作。为什么会有区别?

【问题讨论】:

  • 打印什么?该中间输出与您的预期有何不同?

标签: python list recursion slice


【解决方案1】:
  • a = a[:-1] 创建一个新的列表对象并将其重新绑定到名称 a。所有先前引用名称 a 的堆栈条目都将引用原始的未截断列表。
  • a.pop() 执行删除最后一个元素的就地操作。它不会更改名称 a 所指的内容。所有堆栈条目都将引用截断的列表。

删除最后一个元素重新绑定名称的其他方法是

  • a[:] = a[:-1]。这将获取新列表a[:-1] 并将其分配给a元素。请记住,a[x] = y 形式的任何表达式都会调用type(a).__setitem__(a, x, y),这通常是对a 的就地操作,而a = x 会完全重新绑定名称a
  • del a[-1]。这相当于调用type(a).__delitem__(a, -1)。同样,就地操作与pop 非常相似,只是它不返回元素。
  • a[-1:] = []。这有点类似于a[:] = a[:-1]。与其作为您要保留的所有元素的切片辞职,不如将空分配给您要删除的切片。

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2021-05-30
    • 2017-07-07
    • 2011-08-06
    相关资源
    最近更新 更多