上章我们讲完了浅拷贝,这章我们来讲深拷贝!
我还是把上章的l1复制下来,还是用这个列表来讲。
讲深拷贝我们就需要使用别人给我们写到的功能了,语法也很简单。
直接写一个import,就是倒入的意思,‘import copy’。
导入别人写好的这个copy功能模块这个copy模块下面还有一个功能叫deepcopy。这是别人写好的功能,我们直接拿来用就好了。
我们直接先来打印一下l3,结果确实是拷贝成功了,内容和l1是一样的。
我们接下来看l1和拷贝的l3它们的id是否一样。打印出来两个id完全不一样。说明l3就是一个新的列表。
上章我们讲过了如果列表里面含有可变类型,浅拷贝是没有办法完全区分开的,现在我们来看深拷贝是否能够区分开。
我还是把上章打印列表内部元素id的代码直接拿过来用,我们来看看深拷贝之后的列表内部到底是否还是直接使用原有的内存地址。
从打印的结果我们发现前面两个不可变类型的id号是一样的,但是后面的字列表这个可变类型的id号变了,再来看图。
前面两个不可变类型的id号没变,说明指向的还是原来的值,上章讲浅拷贝的时候也说了,如果列表存的是不可变类型新列表改动之后都是产生新的值,根本不会影响到原列表。
所以说这两个不可变类型仍然指向的是原来的值,这是合理的,因为如果你不改,那我就用同一个值,这样更节省内存空间。
如果你仍然要改,那我就给你产生新的值,申请新的内存空间就行了。
但是针对可变类型深拷贝和浅拷贝就不一样了,深拷贝针对可变类型会产生新的内存地址关键是新产生的这个字列表,它里面存的数据,是用原值还是产生的新值?
我们来打印一下l1的2号索引也就是这个字列表,看它的第一个元素的id号和第二个元素的id号,再来看l3的这个新字列表的第一个元素的id号和第二个元素的id号。我们发现这两个不可变类型任然是实用的原值。
讲到这里我们就明白了,深拷贝针对的容器类型会产生新的容器,针对不可变类型则任然会使用原值,这样更加节省内存空间。
然后我们来修改一下l3,还是把上章的代码复制过来,打印一下看。l1还是原来的数据,l3则是完全被我改掉了。
结果就是这样,两者的数据是完全独立的,没有任何交集。如果你想要拷贝一个列表,并且想让拷贝的列表和原列表完全独立开,就一定要用深拷贝。
未经允许不得转载:445IT之家 » Python 深拷贝是什么