浅拷贝和深拷贝之间有什么区别?[复制]

What are some differences between a Shallow Copy and Deep Copy? [duplicate]

提问人:KAVYA SHARMA 提问时间:11/9/2023 最后编辑:toyota SupraKAVYA SHARMA 更新时间:11/9/2023 访问量:55

问:

我不明白浅拷贝和深拷贝之间的区别。 copy.copy 和 copy.deepcopy() 给出完全相同的输出。 他们的内存位置似乎与其他位置不同,但参考地址让我很困惑。

Python 深拷贝

评论

1赞 3nws 11/9/2023
看看这个

答:

2赞 wim 11/9/2023 #1

深层复制还将复制嵌套容器。也许最好的演示方式是展示一个浅拷贝不足的例子:

>>> import copy
>>> L1 = []
>>> L2 = [L1]
>>> L3 = copy.copy(L2)

现在 L3 是 L2 的浅拷贝。对 L2 本身的修改不会被镜像:

>>> L2.append("x")
>>> L2
[[], 'x']
>>> L3
[[]]

但是,对嵌套列表 L1 的修改将在以下两者中镜像:

>>> L1.append("y")
>>> L2
[['y'], 'x']
>>> L3
[['y']]

如果我们在创建 L3 时使用 instead 而不是,那么嵌套列表 L1 也会被复制。结果是 L3 仍将在最终示例中,而 L3 和 L2 将是真正断开连接的容器。copy.deepcopycopy.copy[[]]

0赞 Abion47 11/9/2023 #2

浅拷贝使用从源复制的属性创建一个新对象。深层副本会创建一个新对象,该对象的属性本身就是基于源属性的新对象。

如果源仅包含基元值,则浅拷贝和深拷贝之间不会有任何区别。当源包含集合或复杂对象的属性时,就会出现差异。请考虑以下几点:

source = [['a', 'b', 'c']]

这里我们有一个源对象,它是一个包含数组的数组。如果我们执行浅拷贝,新对象将包含对同一数组的引用:

target = copy.copy(source)

target[0][0] = 'd'
print(source)
print(target)

# Output:
# [['d', 'b', 'c']]
# [['d', 'b', 'c']]

如您所见,两者的内部数组 和 指向同一个数组。因此,您所做的任何事情都会影响内容,反之亦然。sourcetargettargetsource

相比之下,深层复制不仅复制引用,还递归复制嵌套对象和集合的值:

target = copy.deepcopy(source)

target[0][0] = 'd'
print(source)
print(target)

# Output:
# [['a', 'b', 'c']]
# [['d', 'b', 'c']]

如果 中的内部数组不再与 中的内部数组相同,则内容。它们是两个不同的数组,恰好包含相同的项目。targetsource

这不仅适用于数组。字典、类对象和其他集合在 和 下的行为类似。copydeepcopy

评论

0赞 juanpa.arrivillaga 11/9/2023
术语点:Python 没有“原语”。此外,这些是列表而不是数组。“类对象”,我想,你的意思是类的实例,但每个对象都是 Python 中类的实例。因为类对象,例如 、 、 和 实际上根本不会被复制intstrclass Foo: passFoocopy.deepcopy
0赞 EdvardM 11/9/2023 #3

考虑这个简单的程序:

l = [[2], [4]]
lc = l.copy()  # shallow copy

lc[0][0] = 1

print(lc)   # [[1], [4]] no surprises here
print(l)    # [[1], [4]] because shallow copy

因此,即使您只修改了 ,外部列表中的值(列表)仍然引用相同的匿名内部列表。lc

您是否改用复制到新列表,然后它将递归复制任何嵌套数据结构的值,并且修改不会更改copy.deepcopy()llcl