尽管在 Python 中进行了克隆,但列表的元素发生了变化
Elements of list change despite cloning in Python
在下面的 Python 代码中,我创建了一个包含多个列表的列表 a,然后创建了它的副本 b,但与不包含其他列表的列表不同,当 b改变了,a也随之改变。除了分别复制每个列表之外,有人可以解释如何防止这种情况发生吗?
a = [[None, None, None], [None, None, None], [None, None, None]]
b=a[:]
b[0][0] = 5
a
[[5, None, None], [None, None, None], [None, None, None]]
切片创建了一个新列表,但没有复制列表的内容。因此,a[:]
为您提供了一个新列表,但新列表 b
的内容仍然引用了从 a
.
引用的相同列表
如果您尝试 b[0]=[]
,您会发现可以修改 b
而无需更改 a
,但 b[0][0]
只会修改第一个元素b
中的第一个列表,也是 a
中第一个列表的第一个元素。
b
是 a
的浅拷贝(查看值 id(a[0])
和 id(b[0])
,即使 id(a)
!= id(b)
)。您还需要处理列表中的元素(如果它们是可变的和已修改的,则浅表副本将反映两个地方的更改)。您可以像这样创建一个 deep
副本:
import copy
b = copy.deepcopy(a)
阅读 Python 中的 shallow and deep copy operations。
在下面的 Python 代码中,我创建了一个包含多个列表的列表 a,然后创建了它的副本 b,但与不包含其他列表的列表不同,当 b改变了,a也随之改变。除了分别复制每个列表之外,有人可以解释如何防止这种情况发生吗?
a = [[None, None, None], [None, None, None], [None, None, None]]
b=a[:]
b[0][0] = 5
a
[[5, None, None], [None, None, None], [None, None, None]]
切片创建了一个新列表,但没有复制列表的内容。因此,a[:]
为您提供了一个新列表,但新列表 b
的内容仍然引用了从 a
.
如果您尝试 b[0]=[]
,您会发现可以修改 b
而无需更改 a
,但 b[0][0]
只会修改第一个元素b
中的第一个列表,也是 a
中第一个列表的第一个元素。
b
是 a
的浅拷贝(查看值 id(a[0])
和 id(b[0])
,即使 id(a)
!= id(b)
)。您还需要处理列表中的元素(如果它们是可变的和已修改的,则浅表副本将反映两个地方的更改)。您可以像这样创建一个 deep
副本:
import copy
b = copy.deepcopy(a)
阅读 Python 中的 shallow and deep copy operations。