最近看到老师PPT中关于字典赋值的内容,突然想到自己以前也看过一些深浅拷贝的内容,所以就整理一起发出来。
对于python而言,python的一切变量都是对象,变量的存储,采用引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的值本身,是通过地址去引用值(引用自CSDN某博客)。而在C语言中,变量的值是直接保存在变量的存储区里面。
继续话题赋值、浅拷贝、深拷贝,话不多说,直接上代码:
#coding:utf-8
import copy
#copy ,tuple,不可变类型
a=(4,5,6)
list_0=(1,2,3,a)
list_1=copy.copy(list_0)
list_2=copy.deepcopy(list_0)
list_3=list_0
print "copy,tuple,不可变类型"
print "整体id--->> list_0:%d ,list_1:%d,list_2:%d,list_3:%d" % (id(list_0),id(list_1),id(list_2),\
id(list_3))
print "a的id:--->> list_0[3]:%d,list_1[3]:%d,list_2[3]:%d,list_3[3]:%d" %(id(list_0[3]),id(list_1[3]),\
id(list_2[3]),id(list_3[3]))
#deepcopy,list,可变类型
b=[4,5,6]
arry_0=[1,2,3,b]
arry_1=copy.copy(arry_0)
arry_2=copy.deepcopy(arry_0)
arry_3=arry_0
print"deepcopy,list,可变类型"
print "整体id----deepcopy>> arry_0:%d,arry_1:%d,arry_2:%d,arry_3:%d",(id(arry_0),id(arry_1),id(arry_2),\
id(arry_3))
print "a的id:--->> arry_0[3]:%d,arry_1[3]:%d,arry_2[3]:%d,arry_3[3]:%d",(id(arry_0[3]),id(arry_1[3]),\
id(arry_2[3]),id(arry_3[3]))
C:\Users\user\venv\python_pycharm3\Scripts\python.exe D:/python_pycharm/python_learn/python核心编程/正则表达式/test1.py
copy,tuple,不可变类型
整体id--->> list_0:38546392 ,list_1:38546392,list_2:38546392,list_3:38546392
a的id:--->> list_0[3]:38453824,list_1[3]:38453824,list_2[3]:38453824,list_3[3]:38453824
deepcopy,list,可变类型
整体id----deepcopy>> arry_0:%d,arry_1:%d,arry_2:%d,arry_3:%d (43981320L, 44044488L, 43996552L, 43981320L)
a的id:--->> arry_0[3]:%d,arry_1[3]:%d,arry_2[3]:%d,arry_3[3]:%d (43980104L, 43980104L, 43996488L, 43980104L)
Process finished with exit code 0
代码分为两个部分,一是试验不可变类型的数据结构,比如元组(tuple);另外是可变类型的数据结构(List)。看了好多的技术帖,大多都只分析了可变类型的数据结构,而这与不可变类型的拷贝却并不完全相同。另外,其他技术帖采用的是通过“==”以及“is”来比较,本次试验更简单粗暴,直接比较“ID”。
由运行结果可得:
对不可变类型(tuple)拷贝时,直接赋值方式(“=”),浅拷贝方式“copy”、深拷贝方式“deepcopy”,这三种拷贝方式的结果一样,外层、嵌套层都只是对地址的引用,产生的新对象并不会创造新的地址。因此注意deepcopy对不可变类型的拷贝的特点。
对于可变类型(list)拷贝时,三种方式的拷贝就不完全相同了。在外层的拷贝中,直接赋值方式依然只是对地址的引用,而浅拷贝和深拷贝则是创建了新的地址,因此外层的元素值不会因为arry_0的改变而改变。相反,在嵌套层的拷贝中,只有深度拷贝依然是创建了新的地址,此时的浅拷贝对嵌套层的作用变成了地址引用。这也就是大多数技术帖中所说的浅拷贝只拷贝第一层的原因。
结论:该睡觉了。