深拷贝和浅拷贝的区别

在这里插入图片描述

区别:

浅拷贝只是增加了一个指针指向已存在的内存地址,仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。深拷贝是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。

概述:

浅拷贝可以使用列表自带的copy()函数(如list.copy()),或者使用copy模块的copy()函数。深拷贝只能使用copy模块的deepcopy(),所以使用前要导入:from copy import deepcopy
如果拷贝的对象里的元素只有值,没有引用,那浅拷贝和深拷贝没有差别,都会将原有对象复制一份,产生一个新对象,对新对象里的值进行修改不会影响原有对象,新对象和原对象完全分离开。
如果拷贝的对象里的元素包含引用(像一个列表里储存着另一个列表,存的就是另一个列表的引用),那浅拷贝和深拷贝是不同的,浅拷贝虽然将原有对象复制一份,但是依然保存的是引用,所以对新对象里的引用里的值进行修改,依然会改变原对象里的列表的值,新对象和原对象完全分离开并没有完全分离开。而深拷贝则不同,它会将原对象里的引用也新创建一个,即新建一个列表,然后放的是新列表的引用,这样就可以将新对象和原对象完全分离开。

详解:

首先就上面第二点进行讲解,这里用到一个工具,Python Tutor(http://www.pythontutor.com)是一个对 Python 运行原理进行可视化分析的工具。如下截图。
在这里插入图片描述
这里我们可以看到代码区跟运行原理的图像分析,这里使用copy()函数对列表aa进行拷贝,结果赋值给bb,可以看到内存里新创建一个列表,bb指向的就是这个新创建的列表,跟原本的aa是两个不同的列表,接下来我们对bb[0]的值进行修改为9,看下会如何变化:
在这里插入图片描述
很明显,修改的值是bb列表的值,aal列表没有变化。接下来我们看看深拷贝的:

在这里插入图片描述
看到代码区第3行,这里我们把拷贝函数换成深拷贝函数deepcopy(),然后我们看到右边图像区,很明显bb也是新创建的一个列表,与aa不同,这时我们再对bb[0]的值进行修改为9,可以看到bb列表里的值改变了,aal列表里的没有。到这里,我们已经验证了上面概述里的第二点。接下来让我们看看最重要的第三点的验证:
在这里插入图片描述
这里我们对aa列表做了修改,在aa列表里多添加了一个列表[4,5],然后使用copy()函数对aa进行拷贝赋值给bb,此时看到右边的图像,bb虽然是在内存中新创建了一个列表,但是其index=3的位置存放的还是跟aa列表中一样的引用,他们都指向同一个列表[4,5]。此时我们再修改bb列表里[4,5]中的4为9,执行第四行代码,看下效果:
在这里插入图片描述
很明显,bb里的值改变了,aa里的值也改变了。下面再看看使用深拷贝函数deepcopy()会发生什么?
在这里插入图片描述
这里我们把上面的代码第三行改一下,使用深拷贝函数拷贝aa列表,单点运行到第三行代码,此时我们看到内存里新创建了bb列表,还有就是可以看到bb列表index=3的位置的也是重新创建了新的列表[4,5],很明显区别于浅拷贝,这时,我们再执行第四行代码,修改下bb列表的[4,5]中的4的值为9,看下效果:
在这里插入图片描述
很明显只改变bb列表里列表[4,5]中的4为9,aa中的没有改变,因为它跟原aa列表指向的引用是不同的。这也充分验证了我们概述里讲到的第三点。

参照:https://www.html.cn/qa/other/22051.html
java版的深拷贝和浅拷贝:
https://www.html.cn/qa/other/22850.html
https://blog.csdn.net/riemann_/article/details/87217229

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值