python的深拷贝和浅拷贝
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python的深拷贝和浅拷贝相关的知识,希望对你有一定的参考价值。
参考技术A 1.什么是深拷贝?什么是浅拷贝?(深拷贝与浅拷贝的区别)简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,
如果B没变,那就是深拷贝,自食其力。
也可以这么说: 浅拷贝没有拷贝子对象,所以原始数据改变,子对象会改变;深拷贝,包含对象里面的子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
(1)父对象是可变对象拷贝,只拷贝父对象的的值,不会对其子对象的值进行拷贝而是拷贝的子对象的索引,然后创建一个新的对象(ID地址不一样),如果子对象是可变对象,依然是可以修改的。
(2)父对象是不可变对象的拷贝,就是对另外一个变量的内存地址的拷贝(ID地址一样)或者说对象引用。
import copy
a1=[1,2]
a2=[3,4]
a=[a1,a2]
b=copy.copy(a)#浅拷贝
c=copy.deepcopy(a)#深拷贝
print(id(a)) #140414167869960
print(id(b)) #140414167869896
print(id(c)) #140414167869832
print(id(a[0])) # 140414167868488
print(id(b[0])) #140414167868488
print(id(c[0])) #140414167869768
"""
"""
import copy
a1=(1,2)
a2=(3,4)
a=(a1,a2)
b=copy.copy(a)
c=copy.deepcopy(a)
print(id(a)) #140648248055496
print(id(b)) #140648248055496
print(id(c)) #140648248055496
print(id(a[0])) #140648248055944
print(id(b[0])) #140648248055944
print(id(c[0])) #140648248055944
"""
Python中的深拷贝和浅拷贝
变量、对象、引用之间的关系
- 变量是一个系统表的元素,拥有指向对象的连接的空间
- 对象是被分配的一块内存,存储其所代表的值
- 引用是自动形成的从变量到对象的指针
类型属于对象,不是变量
对象
Python中一切皆对象,如:1,‘a‘,[1,2,3],(1,),{‘a‘:4}
变量
a=3,a就是一个变量
引用
a=3,a引用了对象3
深、浅拷贝
深拷贝和浅拷贝分别对应copy模块的两个方法:deepcopy()和copy()
浅拷贝:只拷贝顶级的对象,或者说:父级对象 a=copy.copy(b)
深拷贝:拷贝所有对象,顶级对象及其嵌套对象。或者说:父级对象及其子对象 a=copy.deepcopy(b)
字典中只有顶级对象
In [38]: dict1={‘name‘:‘tom‘,‘age‘:18} In [39]: import copy In [40]: dict2=copy.copy(dict1) In [41]: dict3=copy.deepcopy(dict1) In [45]: dict2 Out[45]: {‘age‘: 18, ‘name‘: ‘tom‘} In [46]: dict3 Out[46]: {‘age‘: 18, ‘name‘: ‘tom‘} In [52]: id(dict1) Out[52]: 140466748386440 In [53]: id(dict2) Out[53]: 140466741274952 In [54]: id(dict3) Out[54]: 140466749401864 In [47]: dict1[‘age‘]=22 In [48]: dict2 Out[48]: {‘age‘: 18, ‘name‘: ‘tom‘} In [49]: dict3 Out[49]: {‘age‘: 18, ‘name‘: ‘tom‘} In [50]: dict1 Out[50]: {‘age‘: 22, ‘name‘: ‘tom‘} ## 可以看到源字典dict1变了,而深、浅拷贝都没有变
字典中有嵌套对象
In [55]: dict1={‘name‘:{‘first‘:‘tom‘,‘second‘:‘jerry‘},‘city‘:[‘NY‘,‘LA‘]} In [56]: import copy In [57]: dict2=copy.copy(dict1) In [58]: dict3=copy.deepcopy(dict1) In [59]: id(dict1) Out[59]: 140466746666568 In [60]: id(dict2) Out[60]: 140466746816072 In [61]: id(dict3) Out[61]: 140466746724296 In [62]: dict1 Out[62]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘tom‘, ‘second‘: ‘jerry‘}} In [63]: dict2 Out[63]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘tom‘, ‘second‘: ‘jerry‘}} In [64]: dict3 Out[64]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘tom‘, ‘second‘: ‘jerry‘}} In [65]: dict1[‘name‘][‘first‘]=‘john‘ In [66]: dict2 Out[66]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘john‘, ‘second‘: ‘jerry‘}} In [67]: dict3 Out[67]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘tom‘, ‘second‘: ‘jerry‘}} In [68]: dict1 Out[68]: {‘city‘: [‘NY‘, ‘LA‘], ‘name‘: {‘first‘: ‘john‘, ‘second‘: ‘jerry‘}}
所以:
- 深浅拷贝都是对源对象的复制,占用不同的内存空间
- 如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
- 如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝
- 序列对象的切片其实是浅拷贝,即只拷贝顶级的对象
以上是关于python的深拷贝和浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章