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:
相關文件:
- 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 --
<list_reverseiterator object at 0x105baf3d0>
>>>
4.列表的排序算法:timsort
列表對象排序. timsort是工業級算法,其混用插入排序與歸併排序,二分搜索等算法, 亮點是充分利用待排序數據可能部分有序的事實, 並且依據待排序數據內容動態改變排序策略——選擇性進行歸併以及galloping。
- timesort(todo):
- 插入排序
- 二分查找
- 歸併排序:(非兩個兩個歸併, 在a中找到第一個大於b[0]的位置ai, a0,ai-1,b[0], ...)
- gallop_left
- gallop_right
- count_run
- binarysort