0%

Python List 对象

List跟Java的ArrayList、STL中的vector相似。

在Python中的list可以存放任何类型的数据,查看PyListObject可以发现,list实际存放的是PyObject* 指针

PyListObject

list对象是一个变长对象,在运行时动态调整其所维护的内存和元素,并且支持插入删除等操作,list的定义如下:

1
2
3
4
5
6
7
// listobject.h

typedef struct {
PyVarObject ob_base; // 即 PyObject_VAR_HEAD
PyObject **ob_item; // 数组
Py_ssize_t allocated; // 可容纳元素的总数,0 <= ob_size <= allocated
} PyListObject;

注意
self->ob_base->ob_size
self->ob_base->ob_base

其中,ob_size就是list实际拥有的元素数量,allocated指的是实际申请的内存空间,
比如列表A实际申请了5元素的空间,但是此时A只包含了2个元素,则ob_size为2,allocated为5。

图的结构对,但是少了个小写的对象ob_base

List的创建和初始化

PyList_New 创建对象

为了避免频繁的申请内存空间,创建PyListObject的时候会先检查缓冲池是否有可用空间.

list_resize 调整list存储空间

随着list元素的增加,list的存储空间可能会不够用,这个时候就需要扩大list的存储空间。
随着list元素的减少,list的存储空间可能存在冗余,这个时候就需要缩小list的存储空间。
函数list_resize就是用于调节list存储空间大小的

allocated/2 <= newsize <= allocated 时,list_resize只会改变 ob_size不会改变allocated。
其他情况则需要调用PyMem_Realloc函数分配新的空间存储列表元素。

列表allocated的增长模式是 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, …

其公式为 new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6)

后面更改为:

插入、删除

List的添加和删除元素

1
2
3
4
5
append       # 追加元素 PyList_Append
pop
remove # 移除元素 list_remove
insert # 插入元素 PyList_Insert
a[1:3]='' # list_ass_slice

其他操作

PyListObject对象的其他常见操作

1
2
3
4
- 创建PyListObject PyList_New
- 对象赋值 PyList_SetItem
- 获取元素 PyList_GetItem
- 调整list大小 list_resize

参考

  • https://blog.csdn.net/qq_33339479/article/details/81807096