geekdoc-python-zh/docs/askpython/shallow-copy-vs-deep-copy.md

4.0 KiB
Raw Permalink Blame History

Python 中的浅层拷贝与深层拷贝

原文:https://www.askpython.com/python-modules/shallow-copy-vs-deep-copy

在本文中,我们将看看浅层拷贝和深层拷贝之间的区别。我们不时需要在程序中创建各种变量的副本/克隆。这可以通过使用浅层复制或深层复制来完成。

浅拷贝 vs 深拷贝

在本教程中,我们将学习浅拷贝和深拷贝之间的区别。所以让我们开始吧!

浅层复制

让我们看看下面这段代码。

l1 = [[10,20,30],[40,50,60],[70,80,90]]
l2 = list(l1)
print("list 1: ",l1)
print("list 2: ",l2)
l1.append(['I am new element'])
print("new list 1: ",l1)
print("new list 2: ",l2)

代码的输出如下所示。

list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
new list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90], ['I am new element']]
new list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]

现在我们可以看到,l2是使用l1列表创建的。 l2 列表是一个新的独立列表,稍后可以看到。当一个新元素被添加到 l1 时l2 保持不变!

这就是所谓的浅抄!但是现在让我们看看下面给出的代码。

l1 = [[10,20,30],[40,50,60],[70,80,90]]
l2 = list(l1)
print("list 1: ",l1)
print("list 2: ",l2)

l1[2][1] = 'I am changed'
print("new list 1: ",l1)
print("new list 2: ",l2)

你认为输出会是什么?在阅读输出之前,请亲自尝试一下!发现什么奇怪的事了吗?是啊!这次 l2 也变了。

代码的输出如下所示。

list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
new list 1:  [[10, 20, 30], [40, 50, 60], [70, 'I am changed', 90]]
new list 2:  [[10, 20, 30], [40, 50, 60], [70, 'I am changed', 90]]

这背后的原因是,即使 l2 是 l1 的浅拷贝l1 和 l2 的元素仍然引用同一个内存位置。因此,对一个列表的初始元素进行任何修改都会改变第二个列表。

您还可以使用copy模块的 copy函数创建浅层副本,如下面的代码所示。您可以看到输出看起来完全一样。

import copy
l1 = [[10,20,30],[40,50,60],[70,80,90]]
l2 = copy.copy(l1)
print("list 1: ",l1)
print("list 2: ",l2)
print()
l1.append(['new'])
print("new list 1: ",l1)
print("new list 2: ",l2)
print()
l1[2][1] = 'change'
print("new list 1: ",l1)
print("new list 2: ",l2)

代码的输出如下所示。您可以看到输出与前面的方法相同。

list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]

new list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90], ['new']]
new list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]

new list 1:  [[10, 20, 30], [40, 50, 60], [70, 'change', 90], ['new']]
new list 2:  [[10, 20, 30], [40, 50, 60], [70, 'change', 90]]

深度复制

现在让我们运行下面的代码,看看输出的不同。

import copy
l1 = [[10,20,30],[40,50,60],[70,80,90]]
l2 = copy.deepcopy(l1)
print("list 1: ",l1)
print("list 2: ",l2)

l1[2][1] = 'change'
print("new list 1: ",l1)
print("new list 2: ",l2)

这次看到输出很惊讶吧?通过使用同一个模块的copy模块和deepcopy函数,两个列表在所有方面都变得完全相互独立。

深度复制代码的输出如下所示。

list 1:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]
new list 1:  [[10, 20, 30], [40, 50, 60], [70, 'change', 90]]
new list 2:  [[10, 20, 30], [40, 50, 60], [70, 80, 90]]

结论

所以今天我们学习了 Python 中的浅层拷贝和深层拷贝。我们还了解到,浅层拷贝对象只是部分独立于原始对象。而在深度复制中,对象彼此完全独立。

深度复制的缺点之一是比实现浅层复制要慢。两者都可以使用复制模块来实现。

感谢您的阅读!希望你学到了一些东西!