Python:列表及其副本

11

我无法解释以下行为:

l1 = [1, 2, 3, 4]
l1[:][0] = 888
print(l1) # [1, 2, 3, 4]
l1[:] = [9, 8, 7, 6]
print(l1) # [9, 8, 7, 6]

看起来l1[:][0]是对一个副本的引用,而l1[:]则是对对象本身的引用。


6
请参见列表 - Python教程,尤其是对切片进行赋值的部分。 - falsetru
2个回答

13

这是由Python的特性引起的,该特性允许您将一个列表分配给另一个列表的切片,即

l1 = [1,2,3,4]
l1[:2] = [9, 8]
print(l1)

将会把 l1 的前两个值分别设置为 98。同样地,

l1[:] = [9, 8, 7, 6]

l1的所有元素赋予新值。


更多有关赋值的信息,请参考文档


7

l1[:][0] = 888 首先对 l1 中的所有元素进行切片 (l1[:]),这将返回一个新的列表对象,其中包含 l1 中的所有对象-- 它是 l1 的浅拷贝。

然后,它用整数 888 替换该复制列表的第一个元素 ([0] = 888)。

然后,被复制的列表被丢弃,因为没有使用它。

您的第二个示例 l1[:] = [9, 8, 7, 6] 替换 l1 中的所有元素为列表 [9, 8, 7, 6]。这是一次切片赋值。


谢谢你的回答。我的观点是,l1[:] 看起来像是一个副本或者一个对 l1 的引用,这取决于我是改变了一个值还是重新分配整个列表。 - fcracker79
1
它总是复制 l1,除非它是一个赋值操作的目标(你的第二个例子),在这种情况下,它只是替换 l1 的整个内容。 - Max Noel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接