python list.copy浅与深拷贝

python list.copy shallow vs deep copy

本问题已经有最佳答案,请猛点这里访问。

也许我不明白肤浅复制的定义…但我很困惑:

来自文档:

其中"s"是一个列表(但同样的问题分别适用于字典)。

"s.copy() | creates a shallow copy of s (same as s[:])"

但我认为江户记1(0)是一个深刻的复制品。例如,请参阅关于如何复制列表(而不只是指向原始版本)的堆栈溢出答案。使用list1.copy()似乎可以进行深度复制,也就是说,与[:]的行为相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
l1 = [1,2,3,4]
l2 = l1[:]
l3 = l1.copy()



l2.append(5)
l3[0] = 99
print(l1)
print(l2)
print(l3)
>> [1,2,3,4]
>> [1,2,3,4,5]
>> [99,2,3,4]

似乎l1l2l3都是独立的对象。我错过了什么?


在这种情况下,你只是误解了"浅"和"深"的含义。

浅副本仅是顶级元素的副本。如果这些元素中的任何一个本身是列表,那么副本仍将引用原始列表。这就是l1[:]l1.copy()所做的。

深度拷贝是所有级别的拷贝。如果任何元素是列表,那么它们也将被深度复制。不会共享任何引用。这就是copy.deepcopy()所做的。


浅副本意味着新列表保存对旧列表所具有的同一对象的引用。

例如:

1
2
3
4
foo = [1, 2, []]
bar = foo.copy()
bar[-1].append(3)
print(foo)

我们将看到bar中物体的突变也"污染"了foo

如果我们使用深度复制来做这个例子,那么情况就不同了:

1
2
3
4
5
import copy
foo = [1, 2, []]
bar = copy.deepcopy(foo)
bar[-1].append(3)
print(foo)

这是因为深度复制会创建列表的新(深度复制)副本,而不仅仅是复制对旧列表的引用。