python列表是动态数组,底层为连续指针数组,支持o(1)索引访问;采用预分配策略扩容,尾部操作高效,中间操作需移动元素;存储对象引用而非实体,浅拷贝不递归复制。

Python 的 list 并不是传统意义上的链表,而是一个**动态数组(Dynamic Array)**,底层用 C 语言实现,核心是连续内存块 + 预分配策略,兼顾访问效率与插入/删除的灵活性。
连续内存块存储元素指针
Python 列表对象本身(PyListObject)包含三个关键字段:
-
ob_item:指向一个
PyObject **类型的指针数组,即“元素指针的连续数组”——真正存储的是每个元素对象的引用(地址),而非对象本身; - allocated:已分配的插槽数量(内存容量),可能大于当前长度;
-
ob_size:当前实际元素个数(即
len(lst))。
由于只存指针,所有元素在内存中逻辑连续,因此索引访问是 O(1);但元素本身(如整数、字符串等)分散在堆上,列表不负责管理其内存。
预分配机制减少频繁 realloc
为避免每次 append() 都调用 C 的 realloc()(代价高),Python 采用“超额分配(over-allocation)”策略:
立即学习“Python免费学习笔记(深入)”;
本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。 本书内容全面深入,适合各层次PHP和MySQL开发人员阅读,既是优秀的学习教程,也可用作参考手册。
- 当
allocated == ob_size时扩容,新容量按公式近似计算:
new_allocated = (size >> 3) + (size —— 即增长约 12.5% + 小偏移; - 扩容后调用
PyObject_REALLOC重新分配更大连续内存,并复制原指针数组; - 可通过
sys.getsizeof(lst)观察实际占用字节数,它反映的是指针数组大小(不含元素对象本身)。
尾部操作高效,中间操作代价高
得益于连续结构:
-
append()和pop()(无参数)平均 O(1),仅需更新指针和计数器; -
insert(0, x)或pop(0)是 O(n):需整体移动后续所有指针; -
del lst[i]或切片赋值(如lst[2:5] = [])同样触发内存搬移。
若需高频首尾增删,应考虑 collections.deque(双端队列,基于双向链表块实现)。
不可变性与共享引用的注意事项
列表可变,但其内部存储的是对象引用:
- 修改列表元素(如
lst[0] = new_obj)只是改指针,不复制对象; - 多个列表可能共享同一对象引用(如
a = [1]; b = [a, a]),修改a[0]会影响b[0] is b[1]指向的对象; -
list.copy()或lst[:]是浅拷贝——只复制指针数组,不递归拷贝元素对象。
理解这点对调试嵌套结构和内存行为至关重要。









