【问题标题】:Difference between a[:] = b and a = b[:]? (Python)a[:] = b 和 a = b[:] 的区别? (Python)
【发布时间】:2011-08-11 22:07:21
【问题描述】:

我被要求进行编码测试,但不知道答案。有人有什么想法吗?

【问题讨论】:

标签: python sequence slice


【解决方案1】:

[:] 是切片运算符。

当它在左侧时,它会覆盖列表的内容而不创建新的引用。

当它位于右侧时,它会创建一个具有相同内容的列表副本。

【讨论】:

  • 哦,好吧,现在说得通了。澄清一下,在执行 a[:] = b 时 id(a) 不会改变。执行 a = b[:] 时 id(a) 会发生变化。有没有理由说明其中一个可能比另一个更好?
  • 是的,你完全明白了。如果c 也引用与a 相同的列表,那么您可能需要更改内容,以便两个变量都引用更新后的列表。
【解决方案2】:

a = b[:]b 上调用__getslice____getitem__ 并将结果分配给a。在几乎所有情况下(例如列表、元组和其他序列类型),这都会生成序列的浅拷贝;我不知道有任何类不实现该行为,但您可以拥有一个执行不同操作的用户定义类型。之前引用旧值 a 的任何其他对象将继续引用该旧值。

另一方面,a[:] = b 调用__setslice____setitem__a 的元素子集替换为b 序列的元素子集。在这种情况下,如果a 的序列类型表现良好,这将替换整个a,因为没有端点的范围: 表示整个序列。此处的区别在于,不可变类型(例如元组)将不允许您执行 __setslice__(例如,通过抛出 TypeError 异常)。之前引用 a 的任何其他对象也将被更新,因为正在修改底层对象。

对于可变类型,例如lista = b[:] 的结果将与a[:] = b 相同,因为a 将是b 的浅拷贝;对于 tuple 等不可变类型,a[:] = b 无效。对于表现不佳的用户定义类型,所有的赌注都被取消了。与a 引用同一对象的其他对象的情况也有所不同——a = b[:] 引用原始值 (a),但 a[:] = b 引用修改后的值对象(b 的浅拷贝)。

【讨论】:

    【解决方案3】:

    在这两种情况下,您最终的列表 a 是列表 b 的副本。但是用来实现这一点的方法已经改变了。

    a[:] = b 修改列表a 使其具有与b 相同的元素

    a = b[:] 生成一个新列表,该列表是 b 的副本并替换列表 a

    区别在于我们是修改了现有列表还是创建了新列表。

    查看区别:

    a = range(3)
    b = range(4)
    c = a # c and a now share the same list
    a[:] = b
    print "a", a
    print "b", b
    print "C", c
    

    所有三个列表都将打印出来。 C和a共享同一个对象,所以a被修改时c也被修改

    a = range(3)
    b = range(4)
    c = a # c and a now share the same list
    a = b[:]
    print "a", a
    print "b", b
    print "C", c
    

    现在 c 将不会打印出与 a 相同的内容。分配后,ac 没有共享同一个对象。

    Speedwise,a[:] = b' is probably a little faster thena = b[:]`。第一种形式不必创建新的列表对象,它只可以修改现有的列表。其中很大一部分是它可以重用列表已经拥有的内存,而不是分配新的内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      相关资源
      最近更新 更多