深拷贝和浅拷贝的区别是什么

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

本教程操作环境:windows10系统、Dell G3电脑。

概述:

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

详解:

首先就上面第二点进行讲解,这里用到一个工具,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列表指向的引用是不同的。这也充分验证了我们概述里讲到的第三点。

以上就是深拷贝和浅拷贝的区别是什么的详细内容,更多请关注html中文网其它相关文章!

赞(0) 打赏
未经允许不得转载:html中文网首页 » 其他答疑

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏