一维列表与二维列表的浅表复制

时间:2018-09-19 17:23:47

标签: python list shallow-copy

我在Python中发现了很多与“浅表复制”相关的讨论,但我找不到确切的问题。

根据我的理解,创建浅表副本仍然包含对列表原始值的引用。在以下二维列表中也是如此。

>>> x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> y = list(x)
>>> x.append(['New value'])
>>> x
[[1, 2, 3], [4, 5, 6], [7, 8, 9], ['New value']]
>>> y
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> x[0][0] = 'A'
>>> x
[['A', 2, 3], [4, 5, 6], [7, 8, 9], ['New value']]
>>> y
[['A', 2, 3], [4, 5, 6], [7, 8, 9]]

现在,在一维列表中,我没有发现这种效果。

>>> a = [1,2,3,4,5]
>>> b = list(a)
>>> a.append(10)
>>> a
[1, 2, 3, 4, 5, 10]
>>> b
>>> [1, 2, 3, 4, 5]
>>> a[0] = 'A'
>>> a
['A', 2, 3, 4, 5, 10]
>>> b
[1, 2, 3, 4, 5]

任何人都可以澄清这种差异的原因吗?

3 个答案:

答案 0 :(得分:2)

浅拷贝会复制顶级项目,并为每个项目创建一个新实例。如果存在任何复杂的元素,则浅表副本将为这些项目创建新副本,但将为其元素创建新实例。嵌套列表的引用将是新的,但第二级引用仍将是原始对象的引用。

深层复制每个级别创建 each 元素的新实例。副作用是这会使该项目(现在是两个项目)占用的存储空间增加一倍。

在这里您可以看到效果特写。浅表副本b具有每个顶级项的副本。当我们更改标量a[0]时,b中的副本不变。然后,尽管b[2]a[2]不在同一位置,但指针值是相同的:它们指向相同的下层列表。因此,当我们更改a[2][1]时,该更改会反映在b[2][1]中。

>>> a = [1, 2, ['a', 'b', 'c'], 4, 5]
>>> b = list(a)
>>> a[0] = "new 1"
>>> a[2][1] = "Deeper"
>>> a
['new 1', 2, ['a', 'Deeper', 'c'], 4, 5]
>>> b
[1, 2, ['a', 'Deeper', 'c'], 4, 5]

答案 1 :(得分:0)

使用C指针思考。您列出的是很多地址,其中包括自己的列表。您只是在复制整个列表的新实例,但是如果您修改列表中包含的地址上的内容,则会影响此列表。 您在x和y里面的3个三个列表具有相同的地址,但是x和y具有不同的地址。

x == 0x0123  #Hexadecimal addresses
y == 0x0456
x = [0x01, 0x02, 0x03, whatever_you_want]
y = [0x01, 0x02, 0x03]
0x01 = [1, 2, 3]

当我们只是一起分配列表时,如果您写的是y = list(x)而不是y = x,则x和y会同时更改,因为它们将指向相同的地址,例如{{ 1}}。

我不太确定所有事情,但是我可以用我在C语言中的实际知识来理解它

答案 2 :(得分:-2)

列表中的列表是引用,因此即使您复制外部列表,它们也共享相同的内存空间。请注意,如果您替换嵌套列表中的一个列表,它将仅更改其中一个而不更改副本。数字不是参考,因此,当您复制列表时,数字不再共享相同的内存空间