深拷贝浅拷贝


概述

拷贝只复制对象的意思,判断是深拷贝还是浅拷贝看他深层次的数据结构有没有被拷贝。

详情

代码

import copy

a = [1,2,3,4,5,['a','b']]     #原对象
b = a             #赋值,传对象的引用。栈内存地址是同一个指向同一个堆内存地址
c = copy.copy(a)    #对象浅拷贝,列表地址不变但里面具体值已经变了
d = copy.deepcopy(a)    #对象深拷贝,列表和具体值都不会变

print('a=',a,'  id(a)=',id(a),'id(a[5])=',id(a[5]))
print('b=',b,'  id(b)=',id(b),'id(b[5])=',id(b[5]))
print('c=',c,'  id(c)=',id(c),'id(c[5])=',id(c[5]))
print('d=',d,'  id(d)=',id(d),'id(d[5])=',id(d[5]))
print("*"*80)
#变换数值地址不变
a.append(6)
a[5].append('c')
print('a=',a,'  id(a)=',id(a),'id(a[5])=',id(a[5]))
print('b=',b,'  id(b)=',id(b),'id(b[5])=',id(b[5]))
print('c=',c,'  id(c)=',id(c),'id(c[5])=',id(c[5]))
print('d=',d,'  id(d)=',id(d),'id(d[5])=',id(d[5]))

一、以上代码结论得出数据结论如下

1)赋值和被赋值对象,数据保持一致

2)浅拷贝后的对象,如果原数据新增元素,数组元素会新增成功列表内的普通元素不会新增

3)深拷贝后的对象,如果原数据新增元素,数组元素和普通元素都不会变动

二、以上代码得出的id变化结论如下

1.对象赋值:赋值和被赋值指向的堆内存地址一样

2.浅拷贝深拷贝对列表的单个元素的内存地址是一样的如 a[4],c[4],d[4]都是同一个地址。

3.浅拷贝对于a示例列表内嵌套列表(可以把这种看成数组,和数组还是有点区别 数组是保存的同一类型的线程数据结构二列表

是动态的可以是非同一类型的数据结构),a被copy成c后(copy.copy(c))。c的地址改变c的内嵌列表和原对象a的内嵌列表地址一样没有变化

4.深拷贝和3不同,深拷贝d数组的内嵌列表地址和原对象内嵌地址一样

5.原对象、深拷贝、浅拷贝值变更后,地址不变

参考链接:

https://www.cnblogs.com/xiaxiaoxu/p/9742452.html