Python拷贝机制的探究

一、环境配置

OS: Win10 64bit
Python:3.7.4在这里插入图片描述
准备工作
在这里插入图片描述
创建一个list,里面含有字符串、int、list三种数据类型

二、用等号直接赋值

直接用等号赋值
在这里插入图片描述
我们可以看到,list1和list2的ID是一样的。
那么如果我们用不可变类型呢?
在这里插入图片描述

并且由于python对不可变类型赋值的机制,我们可以显然的预见到,显然是一样的。如果改变a的值,id(a)也会变。

因此,我们回过头来讨论list。

在这里插入图片描述
这一步,我们改变了list2[2] 这个元素,可以明显的看到list1跟着改变了。

因为实际上,list2在这里,有点像C++里面的引用,其实指向的是同一块内存区域。

如果我们不想改变list1里的元素怎么办呢?这里就需要用到深拷贝了。

二、浅拷贝

在这里插入图片描述

同样的,让我们做一些准备工作。
我们可以看到,虽然id不同,但是列表内容是相同的。

在这里插入图片描述
上图,我们可以看到,二者的list元素的地址是一样的。
让我们尝试着更改一下list2的元素。
在这里插入图片描述
我们可以看到,list1并没有改变,这是因为list2已经是一个独立于list1的对象。
难道list1与list2通过拷贝的方法就完全独立了吗?那为什么第三个list元素的id完全相同呢?
我们再看下一个例子。

在这里插入图片描述
奇迹发生了,这里的输出又被改变了。
这到底是怎么一回事呢?
细心的读者已经发现了,第一次,实际上是改变的list2[2]的值。
第二次,改变的是list2[2]的 ‘指针’ 所指向的值,因此,二者都改变了。

三、深拷贝

要使list1和list2完全独立,就需要使用深拷贝。

在这里插入图片描述
使用 deepcopy初始化。

在这里插入图片描述

我们可以看到,元素地址已经发生了变化。
本质上来讲,两个list内的list元素已经完全独立了。

让我们试着更改一下:
在这里插入图片描述
可以明显的看到,和浅拷贝不同,list1并没有跟着改变。这就是深拷贝的意义所在。

简单来说,就是list2[2]这个list元素在内存里开辟一块新的区域,独立于list1[2]。

四、总结

如果学过C语言,应该能够从‘’指针‘'的思想入手了解python的拷贝机制。
如果没有了解过C/C++,那么来自菜鸟的一幅图可能会帮助你理解python的拷贝机制。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ftimes/article/details/105860167