拷贝、浅拷贝、深拷贝
今天要分享的是关于python中拷贝、浅拷贝、深拷贝之间的区别。
在正式的内容开始前,我们需要明确一个可变数据类型和不可变数据类型的概念。
- 可变数据类型:值变化,id不发生变化(从始至终都在同一块内存地址上)
- 不可变数据类型:值变化,id也发生变化(值变化后会在另一外内存地址上开辟空间存储新的值)
拷贝(最简单的操作)
lst = [1,5,'DingZhen']
lst1 = lst
print(f'列表lst的地址是{id(lst)},列表lst1的地址是{id(lst1)}')
大家伙可以发现这两个列表的地址根本就是一样的,这样修改一个列表会发生什么捏?
lst[2] = 'Relx gen5'
print(lst1)
显而易见的是,我们修改了列表lst的丁老爷为锐克五代,列表lst1中的丁老爷也变成了瑞克五代。
这是因为lst,lst1这两个变量名实际都指向内存中相同的一片地址,即本质上它们其实是同一个东西。
图示如下(没想到还能有图吧 doge)
浅拷贝
lst = [1,5,'DingZhen'] #丁老爷限时回归
import copy #注意这个是copy库中的方法
lst1 = copy.copy(lst)
print(lst1)
现在看起来是不是和刚才差不多?但是其实上已经不一样了孩子们。
lst[2] = 'Relx gen5' #现在lst列表中的丁老爷已经成锐克了
print(lst)
print(lst1) #接下来让我们看一看列表lst1中的结果吧
我们可以看到lst1中的丁老爷还是在的,这就是浅拷贝。
浅拷贝的图示大概是这样,两个变量名指向的内存地址不同,所以修改了其中一个列表中的丁老爷另一个列表中的丁老爷不会被改变,如下图
深拷贝
这里的概念有一些抽象,同时要用到之前的可变数据类型与不可变数据类型的概念。
首先给大家伙用代码举个例子(使用浅拷贝,可以有效区分深浅拷贝之间的区别)。
lst = [1,5,['DingZhen','Relx gen5']]
lst1 = copy.copy(lst) #上方引用过copy库,这里就不用引用了
print(lst)
print(lst1)
按理说按照之前的例子来说,这里对其中一个列表进行修改另外一个列表不应该受到影响,但是!
lst[2].append('xuebao')
print(lst)
print(lst1)
可以看到两个列表中的丁老爷列表中都多了雪豹,其中浅拷贝的示意图应为
lst = [1,5,['DingZhen','Relx gen5']]
lst1 = copy.deepcopy(lst) #这里使用了深拷贝
print(lst)
print(lst1)
lst[2].append('xuebao')
print(lst)
print(lst1)
可以看到深拷贝中给列表lst添加了雪豹后,列表lst1并没有受到影响。其根本原因是深拷贝将每一个可变数据类型又创建了一遍。
所以就算是再进行改变也不会影响其他的列表