创建一个列表时,系统会分配一定的空间,当新增元素个数超出这个空间时,会自动进行扩容。
这个结论很容易找到,我们可以写一段代码证明一下,内存占用是阶段变化的。
from sys import getsizeof
li = []
for i in range(64):
li.append(i)
print(f'length: {len(li)}, size: {getsizeof(li)}, id: {id(li)}')
# getsizeof() 用于获取一个对象在内存中所占的字节数(不包含引用)
print('hello world!!')
列表不是基于链表的,不过很明显,数组无法扩容,因此需要一套逻辑,才能既使用数组又支持扩容。
我们可以想到两种扩容方案:
- 列表内部封装了多个数组,扩容的时候,直接增加一个新的数组,比如:长度为 23 的 list,由 3 个长度为 8 的小数组拼接而成;
- 列表内部只封装了一个数组,扩容的时候,声明一个更大的数组,将历史数据,复制到新的数组中。
第 2 个方案正确。(第一种方案,需要大量数据,才会提高性能)
可能会产生一个疑问,为什么内存地址(id)会是固定的?不是说数据从一个数组复制到了另一个?
因为 python 中本来就没有数组类型,这个内存地址不是数组的地址,列表也是一种封装后的数据结构。
元组和列表的性能问题
两者都是基于数组的,存取数据的性能上,差别估计不会太大;
从原理上看,列表有初始容量问题,比如:长度为 5、7、9 这样的列表,会预留一部分闲置的空间,初始化阶段,列表必定更加耗时;
获取数组长度的时候,元组可以直接调用 array.length,而列表至少需要一个变量,用于存储当前的数组长度;
当列表和元组内容完全一致,并且,列表刚好用完所有空间的情况下,列表占用的空间仍然会略微大于元组;
因此,元组的性能理论上会高于列表。
可以看看其他人的实验结果:https://zhuanlan.zhihu.com/p/352092425
标签:扩容,python,list,元组,数组,列表,长度,li From: https://www.cnblogs.com/chenss15060100790/p/18581191