Python 列表内存浅析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 列表内存浅析相关的知识,希望对你有一定的参考价值。
参考技术A序列是Python中最基本的数据结构。序列是一种数据存储方式,用来存储一系列的数据。
在内存中,序列就是一块用来存放多个值的连续的内存空间。比如一个整数序列[10,20,30,40]
序列中的每个元素都分配一个数字 - 它的位置,或索引。第一个索引是0,第二个索引是1,依此类推。
列表:用于存储任意数目、任意类型的数据集合。
列表是内置可变序列,是包含多个元素的有序连续的内存空间。列表定义的标准语法格式:
其中,10,20,30,40 这些称为:列表a的元素。
列表中的元素可以各不相同,可以是任意类型。比如:a = [10,20,"abc",True,[]]
当列表增加元素时,列表会自动进行内存管理,减少了程序员的负担。但是列表元素大量移动,效率低所以一般建议在尾部添加。
本地电脑运行结果:
列表是可变数据类型,地址不变,值可变。因此,添加新的值之后,地址也是不变的。
解析:在索引2处要引用50这个元素
申请了8个内存空间但是list实际用来存储元素只使用了其中5个内存空间
insert的时间复杂度是O(n)
pop () 方法 删除并返回指定位置的元素,如果未指定位置则默认操作
pop () 方法 删除并返回指定位置的元素,如果未指定位置则默认操作
结果运行:
python变量内存浅析
1. Python变量
如果把单一值变量称为一维变量,把可以扩展元素的变量称为多维变量,则python的变量可以划分如下:
变量维度 |
Python变量 |
说明 |
|
一维 |
数字 |
int(有符号整型) |
数字类型可以做转换 |
long(长整型[也可以代表八进制和十六进制]) |
|||
float(浮点型) |
|||
complex(复数) |
|||
字符串 |
字符串有丰富的运算符和内嵌函数; 有格式化输出; |
||
二维 |
列表 |
除了元祖外,列表和字典可以灵活的扩展元素 |
|
元组 |
|||
字典 |
2. Python变量的赋值处理
这里主要分析情况为,将原始变量赋值给新变量后,二者的变化关联情况,比如:原始变量为varold,新变量varnew = varold,之后varnew发生了变化,那么varold如何变化,二者的地址情况如何?这里给出测试用例:
用例1:
def whole_modify(value_old, value_new): |
测试结果:
value: (‘aaa‘, 38126200) (‘aaa‘, 38126200) (‘aaa‘, 38126200) (9, 4014992) list: ([‘a‘, 2], 43066072) ([‘a‘, 2], 43066072) ([‘a‘, 2], 43066072) ([3, ‘b‘], 41421080) Dictionary: ({1: ‘a‘, ‘b‘: 2}, 39583440) ({1: ‘a‘, ‘b‘: 2}, 39583440) ({1: ‘a‘, ‘b‘: 2}, 39583440) ({3: ‘c‘}, 39599104) |
用例1中whole_modify是对新变量的整体修改,即直接用=号将一个全新的数据整体赋值给新变量,从测试情况看,结论是:
不论一维还是二维变量,通过=号整体赋值后,新变量会重新分配内存,值为新赋给的值;原变量保持不变。
用例2:
print("list:") |
测试结果:
list: ([‘a‘, 2], 39932832) ([‘a‘, 2], 39932832) ([3, 2], 39932832) ([3, 2], 39932832) dictionary: ({1: ‘a‘, ‘b‘: 2}, 40107728) ({1: ‘a‘, ‘b‘: 2}, 40107728) ({1: ‘a‘, ‘b‘: ‘newvaluestr‘}, 40107728) ({1: ‘a‘, ‘b‘: ‘newvaluestr‘}, 40107728) |
用例2中,主要是对二维变量内部元素做修改(一维变量无需测试),从测试情况看,结论是:
老二维变量被赋给新二维变量后,对二者任何一个的内部元素修改,二者的地址不会发生改变,但值会同步被修改。
3. 分析
Python的变量赋值(包括传参,返回参数等场景),与c/c++区别很大,而且很难用一句话概括其用法。上面两个测试用例主要是从变量类型的角度来区分,具有很强代表性,可以引申到很多场景辅助理解。
很多人将python的变量赋值当做引用看待,这应该是有问题的,比如上面用例1中,很显然就不是引用,因为新变量地址和值都变化了,而老变量完全保持不变。而c/c++引用的概念是,新老变量地址不变,值同步变化。
用例2中对二维变量做局部修改,会发现新老变量的局部元素的地址和值都同步变化了(变量本身地址不变),这个和引用相同的地方是值同步变化了,不同的是变量地址也同步变化了。
Python的这种处理,应该是基于内存效率的考虑,虽然python应用开发中不用考虑变量地址与内存回收,但如果对变量赋值的内存情况完全忽视,则很容易产生意外的结果。
以上是关于Python 列表内存浅析的主要内容,如果未能解决你的问题,请参考以下文章