列表之深浅拷贝

今天遇到了新名词叫深浅拷贝,据说这个东西会在面试有可能被问到,因此我在这里简单捋一下深浅拷贝到底是什么东西。

了解深浅拷贝之前需要先了解数据是怎么被存储在电脑中的

一般情况下,在电脑中新创建一个数据时,系统会给这个数据划分出一个新的空间用于存储数据(这里我用python来简要解释一下)
列表之深浅拷贝
像这里,创建了一个变量a并且赋值为1,那么系统将会分配一个地址给这个数据1将数据存储起来。
然后再来看一下这张图
列表之深浅拷贝
在这里我分别创建了变量a和变量b,并且都赋值1,但是两个变量的存储地址是一样的,这表明了变量只是一个指针,可以指向系统所含有的数据,而不是会重新创建一个一模一样的数据。图示如下:
列表之深浅拷贝

也就是说变量可以有很多个,但是数据只能有一个!

上面是基础数据类型的存储模式,接下来是列表(list)的存储模式

列表的存储模式

在python中列表的表现形式如下:
a = [1, 2, 3, “b”, “+”, “tree”]
这是一个简单的列表。列表可以理解为一个装着东西袋子,列表中的数据可以理解为袋子里装的东西。袋子可以不装东西,列表也可以为空。
列表之深浅拷贝


当计算机存储列表时,会给列表分配一个存储地址,然后对列表内部的数据也会分配一个存储地址。图示如下:

列表之深浅拷贝
上面是存储的是普通数据的列表,当列表中嵌套列表时会稍微复杂一些
代码表达式:
b = [“Big”, “Tree”]
a = [1, 2, 3, 4, b]
a列表中包含列表b,这就是列表嵌套列表,当存在列表嵌套时,我们可以对嵌套的列表进行分层,a列表成为第一层,b列表成为第二层,如果还有嵌套的话就依次递增下去。
下面的是电脑存储这种类型列表数据的示例:
列表之深浅拷贝

了解完列表存储数据的流程后,接下来理解深浅拷贝就容易多啦!

拷贝就是copy,也就是复制的意思。
深浅拷贝顾名思义就存在深拷贝和浅拷贝两种情况。
b = [“Big”, “Tree”]
a = [1, 2, 3, 4, b]
浅拷贝:a.copy() 这样a列表就完成了一次浅拷贝
深拷贝:
import copy
c = copy.deepcopy(a)
这样a列表就完成了一次深拷贝。
浅拷贝a.copy()等价于copy.copy(a)

深拷贝和浅拷贝的区别

浅拷贝只拷贝第一层的即a列表的存储数据地址,如果此时b列表发生了修改,则c列表中b列表的数据也会发生变化,此时数据复制的结果就会不准确。图示如下:
列表之深浅拷贝
代码如下:
列表之深浅拷贝
可以看到只在a的内部发生了数据的修改时,c的数据没有发生变化。接下来看看b内部发生变动的情况是怎样的。
列表之深浅拷贝
这时我们发现吧列表发生了修改时,c列表的数据也随之变化,此时数据复制则出现了不确定性,不能完全备份修改前的数据。这是因为c中只存储的是b列表的存储地址,而不是b的数据,所以,当b更新后,c中的把列表地址就会指向更新后的b列表,导致数据发生变化。

为了杜绝这种情况,我们需要进行深拷贝,把进行嵌套的所有列表数据都复制一遍,这样不管哪一层数据发生变化,对我们已经复制的数据都不会产生影响。
列表之深浅拷贝

代码展示:
列表之深浅拷贝
这时候可以发现,不管原来的列表怎么发生变化,c列表都不会发生变化,这就是深拷贝的好处。