Python浅拷贝和深度拷贝
前面介绍了Python的赋值(对象的引用传递),那么Python如何解决原始数据在函数传递后不受影响呢,Python提供了浅度拷贝(shallowcopy)和深度拷贝(deepcopy)两种方式。
·浅拷贝(copy):拷贝父对象,不拷贝对象内部的子对象。
·深拷贝(deepcopy):完全拷贝了父对象及其子对象。
浅拷贝
1.不可变数据类型
下面对不可变对象整型变量和元组进行浅拷贝:
importcopy
a=1
b=copy.copy(a)
print(id(a))
print(id(b))
print(a==b)
print(aisb)
t1=(1,2,3)
t2=tuple(t1)
print(id(t1))
print(id(t2))
print(t1==t2)
print(t1ist2)
执行结果:
50622072
50622072
True
True
55145384
55145384
True
True
不可变对象的拷贝和对象的引用传递一样,a、b指向相同的对象,修改其中一个变量的值不会影响另外的变量,会开辟新的空间。
2.可变数据类型
对可变对象list进行浅拷贝:
importcopy
l1=[1,2,3]
l2=list(l1)
l3=copy.copy(l1)
l4=l1[:]
print(id(l1))
print(id(l2))
print(l1==l2)
print(l1isl2)
print(id(l3))
print(id(l4))
l1.append(4)
print(id(l1))
print(l1==l2)
print(l1isl2)
执行结果:
48520904
48523784
True
False
48523848
48521032
48520904
False
False
可以看到,对可变对象的浅拷贝会重新分配一块内存,创建一个新的对象,里面的元素是原对象中子对象的引用。改变l1的值不会影响l2,l3,l4的值,它们指向不同的对象。
上面的例子比较简单,下面举一个相对复杂的数据结构:
importcopy
l1=[[1,2],(4,5)]
l2=copy.copy(l1)
print(id(l1))
print(id(l2))
print(id(l1[0]))
print(id(l2[0]))
l1.append(6)
print(l1)
print(l2)
l1[0].append(3)
print(l1)
print(l2)
执行结果:
1918057951816
1918057949448
2680328991496
2680328991496
[[1,2],(4,5),6]
[[1,2],(4,5)]
[[1,2,3],(4,5),6]
[[1,2,3],(4,5)]
l2是l1的浅拷贝,它们指向不同的对象,因为浅拷贝里的元素是对原对象元素的引用,因此l2中的元素和l1指向同一个列表和元组对象(l1[0]和l2[0]指向的是相同的地址)。l1.append(6)不会对l2产生任何影响,因为l2和l1作为整体是两个不同的对象,不共享内存地址。
l1[0].append(3)对l1中的第一个列表新增元素3,因为l2是l1的浅拷贝,l2中的第一个元素和l1中的第一个元素,共同指向同一个列表,因此l2中的第一个列表也会相对应的新增元素3。
这里提一个小问题:如果对l1中的元组新增元素(l1[1]+=(7,8)),会影响l2吗?
到这里我们知道使用浅拷贝可能带来的副作用,要避免它就得使用深度拷贝。
深度拷贝
深度拷贝会完整地拷贝一个对象,会重新分配一块内存,创建一个新的对象,并且将原对象中的元素以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联,也就是完全拷贝了父对象及其子对象。
importcopy
l1=[[1,2],(4,5)]
l2=copy.deepcopy(l1)
print(id(l1))
print(id(l2))
l1.append(6)
print(l1)
print(l2)
l1[0].append(3)
print(l1)
print(l2)
执行结果:
3026088342280
3026088342472
[[1,2],(4,5),6]
[[1,2],(4,5)]
[[1,2,3],(4,5),6]
[[1,2],(4,5)]
可以看到,l1变化不影响l2,l1和l2完全独立,没有任何联系。
在进行深度拷贝时,深度拷贝deepcopy中会维护一个字典,记录已经拷贝的对象与其ID。如果字典里已经存储了将要拷贝的对象,则会从字典直接返回。
以上内容为大家介绍了Python浅拷贝和深度拷贝,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注IT培训机构:千锋教育。http://www.mobiletrain.org/

相关推荐HOT
更多>>
如何使用Pandas处理Excel?
如何使用Pandas处理Excel?做过行政或者人事,或者对此有过了解的小伙伴,一定对下发各个部分的表有着非常深刻的印象,最常见的就是需要我们将一...详情>>
2023-11-14 07:43:15
python中np.insert()函数的使用方法
python中np.insert()函数的使用方法在numpy数组操作中,np.append()方法可以在每行每列的最后添加数据,但其位置是规定的,那如果想要指定添加...详情>>
2023-11-14 05:06:13
SVM在python中的原理如何理解?
SVM在python中的原理如何理解?在python中除了编程化的知识点外,对于数学方法的算法也有所涉及,SVM就是一种很好地体现。我们学习过数学中的坐...详情>>
2023-11-14 04:30:04
python处理绝对路径和相对路径函数有哪些?
python处理绝对路径和相对路径函数有哪些?绝对路径和相对路径是什么?绝对路径:从根文件夹开始,Windows系统以盘符(C:)作为根文件夹,OSX或Lin...详情>>
2023-11-14 03:33:02热门推荐
如何使用python any()判断多元素?
沸如何使用Pandas处理Excel?
热python函数中的参数有哪些?
热python中pygal模块如何使用?
新Python的excel处理操作
python中doctest库是什么?
python中series是什么意思
python中np.insert()函数的使用方法
SVM在python中的原理如何理解?
Python描述符中有哪三种方法?
python处理绝对路径和相对路径函数有哪些?
python单继承和多继承如何定义?
python封装中的私有如何理解?
python模块引入的三种方式
技术干货






