python列表中存类对象_cpython: 列表对象的三种形态

cpyhton list 三种对象类型

PyList_Type

PyListIter_Type

PyListRevIter_Type

解释器相关:

_PyList_Fini: 释放解释器中list缓存池,加速分配。

// PyInterpreterState

struct _Py_list_state list;

define PyList_MAXFREELIST 80

struct _Py_list_state {

PyListObject *free_list[PyList_MAXFREELIST];

int numfree;

};

UML:

0f5e3b58882517c051f0e88a05021f2d.png

相关文件:

cpython/Objects/listobject.c

cpython/Objects/clinic/listobject.c.h

cpython/Include/listobject.h

cpython/Objects/listsort.txt

2.0 List

list对象相关api.

PyList_Type

list_length: O(1)获取列表长度

list_contains: O(n) 判定是否包含

list_extend: 触发列表扩容.resize 增大

list_pop_impl: 触发列表收缩.resize 减小

list_slice: 切片

PyList_GetSlice

list_slice

list_ass_slice

list_slice

list_copy_impl

list_slice

部分函数源码分析:

static Py_ssize_t

list_length(PyListObject *a)

{

/* O(1) 获取可变对象头中.ob_size*/

return Py_SIZE(a);

}

static int

list_contains(PyListObject *a, PyObject *el)

{

PyObject *item;

Py_ssize_t i;

int cmp;

/* O(n) 变量比较 */

for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(a); ++i) {

item = PyList_GET_ITEM(a, i);

Py_INCREF(item);

cmp = PyObject_RichCompareBool(item, el, Py_EQ);

Py_DECREF(item);

}

return cmp;

}

static PyObject *

list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)

{

PyListObject *np;

PyObject **src, **dest;

Py_ssize_t i, len;

// 1.先计数新的切片后list对象的长度(size, ob_item指针的空间), 然后分配新的list对象np

len = ihigh - ilow;

np = (PyListObject *) list_new_prealloc(len);

if (np == NULL)

return NULL;

src = a->ob_item + ilow;

dest = np->ob_item;

// 2.copy 源list对象的ob_item到新的list对象np的ob_item, 增加引用计数

// copy的是列表中元素PyObject对象的指针. O(n)

for (i = 0; i < len; i++) {

PyObject *v = src[i];

Py_INCREF(v);

dest[i] = v;

}

Py_SET_SIZE(np, len);

return (PyObject *)np;

}

2.1 List Iterator

PyListIter_Type

listiter_*

迭代器协议

__iter__: self

__next__:

eg: listiter_next 实现

static PyObject *

listiter_next(listiterobject *it)

{

PyListObject *seq;

PyObject *item;

assert(it != NULL);

// 1.获取当前list对象

seq = it->it_seq;

if (seq == NULL)

return NULL;

assert(PyList_Check(seq));

if (it->it_index < PyList_GET_SIZE(seq)) {

// 2.获取索引标记位置的对象, 索引位置++. 正向遍历

item = PyList_GET_ITEM(seq, it->it_index);

++it->it_index;

Py_INCREF(item);

return item;

}

it->it_seq = NULL;

Py_DECREF(seq);

return NULL;

}

2.2 List Reverse Iterator

PyListRevIter_Type

listreviter_*

eg: listiter_next 实现

static PyObject *

listreviter_next(listreviterobject *it)

{

PyObject *item;

Py_ssize_t index;

PyListObject *seq;

assert(it != NULL);

// 1.取出当前list对象

seq = it->it_seq;

if (seq == NULL) {

return NULL;

}

assert(PyList_Check(seq));

index = it->it_index;

if (index>=0 && index < PyList_GET_SIZE(seq)) {

item = PyList_GET_ITEM(seq, index);

// 2.取出索引位置的对象,索引位置--(反向遍历)

it->it_index--;

Py_INCREF(item);

return item;

}

it->it_index = -1;

it->it_seq = NULL;

Py_DECREF(seq);

return NULL;

}

3. list -> iter -> Reverse iter

>>>d = [1, 2, 3] # 创建了d, d是一个列表对象

>>>[i for i in d] # 此时,触发d有列表对象生成listiterobject, 在for..in指令的上下文中

>>> c = d.__reversed__() # list => list_reverseiterator

>>> c # c 是反向的迭代器. it_index = 2, next 调用时,it_index --

>>>

4.列表的排序算法:timsort

列表对象排序. timsort是工业级算法,其混用插入排序与归并排序,二分搜索等算法, 亮点是充分利用待排序数据可能部分有序的事实, 并且依据待排序数据内容动态改变排序策略——选择性进行归并以及galloping。

timesort(todo):

插入排序

二分查找

归并排序:(非两个两个归并, 在a中找到第一个大于b[0]的位置ai, a0,ai-1,b[0], ...)

gallop_left

gallop_right

count_run

binarysort

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值