天天看点

Python中的数据存储以及拷贝详解

作者:刘聪明LCM

引言:

在本人逛头条的过程中,经常看到有创作者出形如下图的题目考各位条友,似乎该类题目天生自带流量,今天我将就我所知道的相关内容浅谈一二。

Python中的数据存储以及拷贝详解

输出结果应为:[12306,119,120]

一、Python中的数据对象怎么存储

1.数组的数据存储

在其他高级语言当中,有一类叫数组的数据结构,在创建数组对象时,一般都要事先声明所创对象的数据类型和大小,这两个属性一旦确定,后续能存入这个数组对象的元素就被限定。

Python中的数据存储以及拷贝详解

示例

如示例数组a,假设它是一个整数数组,每个元素占4个字节,数组从内存首地址10开始顺序存放元素,那么数据存放情况就应该大致如图所示,在知道首地址和每个元素所占内存的情况下,我们要访问其中的数据,比如120,就可以直接查找开始内存为10+4*2的这个元素,这也是数组访问元素的方法。(对于这部分的知识点我不太清楚,如有错误还望指正!)

2.Python列表的数据存储

而在Pythom当中,创建数据对象不用声明对象的类型和大小,Python中的列表与数组非常相似,但有两个明显区别,1.列表对象可以随意扩充;2.列表对象中的元素类型可以不相同。

对于a = [[1,2,3],3.14,'python']这样的一个赋值语句,实际的数据存储情况可能如下图。

Python中的数据存储以及拷贝详解

示例

变量a通过id内存地址指向最外层的列表,而内存的列表、浮点数、字符串又通过各自的id指向相应的元素,访问元素的时候一层层通过id进行查找,由于id大小都是一样的,因此元素的类型就可以不相同。

二、相等和相同

我们在判断两个对象是否相等时,一般会用到==比较运算符,这个其实比较的是两个对象的值是否一样,只要值是一样的,返回的结果就是True,而判断两个对象是否相同(为同一个对象)则需要用到is身份运算符,只有当两个对象的id也就是内存地址一样时,返回的结果才是True,显然,相同的对象肯定相等,但相等的对象不一定相同。

我们可以用id()函数查看对象的内存地址。

Python中的数据存储以及拷贝详解

id函数的解释

Python中的数据存储以及拷贝详解

示例

三、赋值语句

赋值语句包括等于(=)、加等于(+=)、减等于(-=)等等,将一个对象赋值给一个变量是指创建一个引用,将变量指向对象。

在文章开头的那个问题当中,我们先创建一个变量a指向一个列表对象,然后又将变量a赋值给变量b,其实就相当于创建了一个新的变量b,它和变量a具有相同的引用,都指向[110,119,120]这个列表对象,因此在通过变量b修改这个列表对象后,通过变量a访问这个列表对象时会显示为修改后的样子,因为自始至终内存中都只有一个列表对象。

四、两个机制

1.小整数池对象机制

Python解释器为了节约内存、提高效率,会将我们常用的小整数装入对象池,这些小整数在Python解释器中会提前创建好,所有位于这个范围内的数都将使用同一个对象,对于单个字母也是这样的机制,小整数池的范围是[-5,256]。

Python中的数据存储以及拷贝详解

示例

2.字符串驻存机制

字符串只包含大小写字母、数字、下划线时,采用驻存机制,即内存中只存储一个相同的字符串对像。

Python中的数据存储以及拷贝详解

示例

五、浅拷贝

浅拷贝通俗的讲指仅在第一个维度创建了新副本,在第一个维度修改其中一个变量时,另一个变量不会改变。

浅拷贝的常见方式:

1.数据构造方法

Python中的数据存储以及拷贝详解

示例

2.切片

Python中的数据存储以及拷贝详解

示例

3.copy()函数

Python中的数据存储以及拷贝详解

示例

但是,浅拷贝在更深的维度修改一个变量时,另一个变量也会跟着改变,这就是叫浅拷贝的原因。

Python中的数据存储以及拷贝详解

示例

从示例中我们可以看到,变量b是变量a的浅拷贝,我们在第一个维度修改变量a时,变量b没有跟着改变,而在第二个维度修改变量a时,变量b却跟着改变了。

这是因为变量a和变量b中的内嵌列表还是具有相同的引用。

Python中的数据存储以及拷贝详解

示例

六、深拷贝

深拷贝相对于浅拷贝而言,则是完全创建了一个新的副本,新旧变量是两个完全不同的对象,因此不管怎么改变其中一个变量,另一个变量都不会改变。

Python中的数据存储以及拷贝详解

示例