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

134 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Python 中的浅层拷贝与深层拷贝
> 原文:<https://www.askpython.com/python-modules/shallow-copy-vs-deep-copy>
在本文中,我们将看看浅层拷贝和深层拷贝之间的区别。我们不时需要在程序中创建各种变量的副本/克隆。这可以通过使用浅层复制或深层复制来完成。
## **浅拷贝 vs 深拷贝**
在本教程中,我们将学习浅拷贝和深拷贝之间的区别。所以让我们开始吧!
### 浅层复制
让我们看看下面这段代码。
```py
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)
```
代码的输出如下所示。
```py
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 保持不变!
这就是所谓的浅抄!但是现在让我们看看下面给出的代码。
```py
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 也变了。
代码的输出如下所示。
```py
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`函数](https://www.askpython.com/python-modules/python-copy)创建浅层副本,如下面的代码所示。您可以看到输出看起来完全一样。
```py
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)
```
代码的输出如下所示。您可以看到输出与前面的方法相同。
```py
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]]
```
### 深度复制
现在让我们运行下面的代码,看看输出的不同。
```py
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`函数,两个列表在所有方面都变得完全相互独立。
深度复制代码的输出如下所示。
```py
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 中的浅层拷贝和深层拷贝。我们还了解到,浅层拷贝对象只是部分独立于原始对象。而在深度复制中,对象彼此完全独立。
深度复制的缺点之一是比实现浅层复制要慢。两者都可以使用复制模块来实现。
感谢您的阅读!希望你学到了一些东西!