134 lines
4.0 KiB
Markdown
134 lines
4.0 KiB
Markdown
# 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 中的浅层拷贝和深层拷贝。我们还了解到,浅层拷贝对象只是部分独立于原始对象。而在深度复制中,对象彼此完全独立。
|
||
|
||
深度复制的缺点之一是比实现浅层复制要慢。两者都可以使用复制模块来实现。
|
||
|
||
感谢您的阅读!希望你学到了一些东西! |