Python中深拷贝与浅拷贝的区别?
公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助!
小猿会从最基础的面试题开始,每天一题。如果参考答案不够好,或者有错误的话,麻烦大家可以在留言区给出自己的意见和讨论,大家是要一起学习的 。
废话不多说,开始今天的题目:
问:说说Python中深拷贝与浅拷贝的区别?
答:Python中如果需要拷贝对象,需要使用标准库中的copy模块。而说到copy模块,不得不说的就是深拷贝与浅拷贝。
深拷贝和浅拷贝需要注意的地方就是:可变元素的拷贝
在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的。也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的。但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别 。(PS:这句话如果看不懂,请先看下面的代码演示,回过头来再看,就比较好理解了 。)
下面分别来说说这两者的区别:
代码例子来源于: https://www.cnblogs.com/feiqiangsheng/p/11026911.html
1、浅拷贝
使用copy模块里面的copy方法实现。
改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;
改变原始对象中为不可变类型的元素的值,不会响拷贝对象。
#定义一个列表,其中第一个元素是可变类型。
list1 = [[1,2], 'fei', 66];
#进行浅copy
list2 = copy.copy(list1);
#对象地址是否相同。
print(id(list1));
print(id(list2));
#结果:不同
46177816
46177936
#第一个元素地址是否相同。
print(id(list1[0]));
print(id(list2[0]));
#结果:相同
46240432
46240432
#第二个元素地址是否相同。
print(id(list1[1]));
print(id(list2[1]));
#结果:相同
45547328
45547328
#改变第一个值,查看复制对象变化。
list1[0][0] = 2;
print(list2);
#结果:复制对象发生变化
[[2, 2], 'fei', 66]
#改变第二个值,查看复制对象变化。
list1[1] = 'ge';
print(list2);
#结果:复制对象没发生变了
[[2, 2], 'fei', 66]
2、深拷贝
copy模块里面的deepcopy方法实现。
深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。
原始对象和拷贝对象所有的可变元素地址都不一样了。
#定义一个列表,其中第一个元素是可变类型。
list1 = [[1,2], 'fei', 66];
#进行深copy
list2 = copy.deepcopy(list1);
#对象地址是否相同。
print(id(list1));
print(id(list2));
#结果:不同
46177816
46177936
#第一个元素地址是否相同。
print(id(list1[0]));
print(id(list2[0]));
#结果:不同
49123856
49588784
#第二个元素地址是否相同。
print(id(list1[1]));
print(id(list2[1]));
#结果:相同
45547328
45547328
#改变第一个值,查看复制对象变化。
list1[0][0] = 2;
print(list2);
#结果:复制对象没发生变了
[[1, 2], 'fei', 66]
#改变第二个值,查看复制对象变化。
list1[1] = 'ge';
print(list2);
#结果:复制对象没发生变了
[[1, 2], 'fei', 66]
Python深浅拷贝总结:
1,深浅拷贝都是对源对象的复制,占用不同的内存空间。
2,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
3,可变类型的对象:值相等,地址不相等 。
如果对于参考答案有不认同的,大家可以在评论区指出和补充,欢迎留言!
更多题目:
关注小猿公众号,每天学习一道题