Python学习笔记_浅拷贝,深拷贝

时间:2021-02-11 19:54:16

做一道练习题时突然发现之前忽略了这一块的内容,遂填坑一番记录一下

Python学习笔记_浅拷贝,深拷贝

图中,old2是直接赋值,new等于old的切片,new2是利用old的内建函数copy得到的,随后,利用sort()对old进行排序后,发现old2随之改变,而new、new2没有改变,查看他们的内存id可知,old2与old引用的内存是一模一样的,也就是说利用=直接赋值就是给该内存内容加了一个标签,old对该内存中的内容进行改变后,其余的引用结果都会跟着改变。

new和new2都在新的内存中将old的内容实实在在的拷贝了一份,所以old得操作不会影响它们。help(old.copy)后看到 a shallow copy of L ,才知道这些叫浅拷贝。

浅拷贝

Python学习笔记_浅拷贝,深拷贝

在这个例子中,对old浅拷贝得到old2,它们的内存地址如上个例子中一样发生了改变,但把list中的内容地址打印出来后发现它们引用的对象其实是同一个,及old中的1003和old2中的1003在内存中是同一个,如下图所示,Python学习笔记_浅拷贝,深拷贝

此时,改变了old[0]的值,即old[0]引用了新的内存处的新的值,为什么不是改变1000这个内存地址的值?因为在pytho中int、float、string和tuple皆是不可变类型,例 i += 1 并不是真的在原有的int对象上+1,而是重新创建一个value为6的int对象,i引用自这个新的对象,所以在此处,old[0]引用了新的对象。而改变old[1][0]的值,old2也跟着改变了,因为list是可变类型,如图中,old和old2同时引用list[1001,1002],当改变list[0]的值时,根据之前int不可变类型的原因,list[0]引用了新的对象,但注意,此时并没有改变old、old2对list的引用,它们仍引用的是id为44717320处的list,所以,old和old2打印出来的值都变化了。

(解释一下,此处使用1000,1001,1002等大数据值的原因,因为之前自己练手的时候不太懂这其中引用的原理,用的是1,2,3等小值数据,看到old,old2引用相同的内存地址以为是python有小数缓存机制(缓存【-5,256】)的原因,所以用了较大的数又测了一下,弄懂之后才发现并没有影响。)

深拷贝

深拷贝需要用到python copy包

copy.copy() :浅复制

copy.deepcopy():深复制

Python学习笔记_浅拷贝,深拷贝

修改后,经过深拷贝得到的old2里,对所有可变类型进行了拷贝(嵌套多层也进行了拷贝),虽然两个list引用的对象仍然相同,但根据之前的不可变类型原因,old和old2的引用并不会相互影响。Python学习笔记_浅拷贝,深拷贝

多层可变类型验证

Python学习笔记_浅拷贝,深拷贝