深拷贝和浅拷贝Python,python切片是深拷贝还是浅拷贝

  深拷贝和浅拷贝Python,python切片是深拷贝还是浅拷贝

  概述:

  浅层复制可以使用list自带的copy()函数(比如list.copy())或者复制模块的copy()函数。Deepcopy只能使用copy模块的deepcopy(),所以使用前先导入:from copy导入deepcopy如果被复制对象中的元素只有值没有引用,那么浅复制和深复制没有区别,所以会复制原来的对象,生成一个新的对象。修改新对象中的值不会影响原始对象,新对象将与原始对象完全分离。如果复制对象中的元素包含引用(就像存储在一个列表中的另一个列表一样,存储在另一个列表中的引用),则浅拷贝不同于深拷贝。尽管轻型副本复制了原始对象,但它仍保留引用,因此修改新对象中引用的值仍会更改原始对象列表中的值。新对象与原始对象完全分离,但没有完全分离。而深拷贝则是在原对象中创建一个新的引用,即创建一个新的列表,然后放上新列表的引用,这样新对象就可以完全脱离原对象。详细解释:

  首先说明上面的第二点。这里使用了一个工具。Python Tutor(http://www.pythontutor.com)是一款可视化分析Python运行原理的工具。下面截图。

  这里可以看到码区和运算原理的图像分析。这里,使用copy()函数复制列表aa,并将结果赋给bb。你可以看到内存中创建了一个新的列表,bb指向这个新创建的列表,和原来的aa是两个不同的列表。接下来,我们将bb[0]的值修改为9,看看它会如何变化:

  显然,修改后的值是bb列表的值,而aal列表没有改变。接下来,我们来看看深度文案:

  参见代码区的第3行,这里我们将copy函数改为deepcopy函数deepcopy(),然后我们看到右边的图像区。很明显,bb也是新创建的列表,和aa不一样。此时,我们将bb[0]的值修改为9,可以看到bb列表中的值发生了变化,而aal列表中的值没有变化。到目前为止,我们已经验证了上述概述中的第二点。接下来,我们来看最重要的第三点的验证:

  这里我们修改了aa列表,在aa列表[4,5]中增加了一个额外的列表,然后使用copy()函数复制aa并赋给bb。这时,我们可以看到右边的图像。虽然bb在内存中创建了一个新的链表,但是它的index=3位置存储的引用与aa链表中的相同,它们都指向同一个链表[4,5]。此时,我们将bb list中的[4,5]中的4改为9,执行第四行代码,看看效果:

  显然bb里的值变了,aa里的值也变了。让我们来看看使用deepcopy函数deepcopy()时会发生什么。

  这里我们修改上面代码的第三行,使用深度复制函数复制aa列表,单点运行到第三行代码。这时我们可以看到内存中已经创建了一个新的bb链表,在bb链表的index=3可见的地方也重新创建了新的链表[4,5],这与轻拷贝明显不同。这时我们会执行第四行代码,修改bb链表[4,5]中4的值。

  很明显,bb链表中只有list [4,5]中的4改为9,而aa链表中的引用不变,因为它与原aa链表中指向的引用不同。这也充分验证了我们概述中提到的第三点。

  看了网上那么多介绍,印象最深的还是自己总结做记录。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: