【摘要】今天给大家解答一道Python常见的面试题,希望这个面试栏目,给那些准备面试的同学,提供一点点帮助!小编会从最基础的面试题开始,每天一题。如果参考答案不够好,或者有错误的话,麻烦大家可以在留言区给出自己的意见和讨论,今天要说的是Python中深拷贝与浅拷贝的区别。
废话不多说,开始今天的题目:
问:说说Python中深拷贝与浅拷贝的区别?
答:Python中如果需要拷贝对象,需要使用标准库中的copy模块。而说到copy模块,不得不说的就是深拷贝与浅拷贝。
深拷贝和浅拷贝需要注意的地方就是:可变元素的拷贝
在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的。也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的。但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别 。(PS:这句话如果看不懂,请先看下面的代码演示,回过头来再看,就比较好理解了 。)
下面分别来说说这两者的区别:
1、浅拷贝
使用copy模块里面的copy方法实现。
改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;
改变原始对象中为不可变类型的元素的值,不会响拷贝对象。
import copy#定义一个列表,其中第一个元素是可变类型。
list1 = [[1,2], 'fei', 66];#进行浅
copylist2 = copy.copy(list1);#对象地址是否相同。
print(id(list1));print(id(list2));#结果:不同4617781646177936#第一个元素地址是否相同。
print(id(list1[0]));print(id(list2[0]));#结果:相同4624043246240432#第二个元素地址是否相同。
print(id(list1[1]));print(id(list2[1]));#结果:相同4554732845547328#改变第一个值,查看复制对象变化。
list1[0][0] = 2;print(list2);#结果:复制对象发生变化[[2, 2], 'fei', 66]#改变第二个值,查看复制对象变化。
list1[1] = 'ge';print(list2);#结果:复制对象没发生变了[[2, 2], 'fei', 66]
2、深拷贝
copy模块里面的deepcopy方法实现。
深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。
原始对象和拷贝对象所有的可变元素地址都不一样了。