Python有很大實現的版本,像拿C語言實現的Cpython,以及在其基礎上改進其解釋執行變為即時編譯(jit)的Pypy,還有一些其他的比如Jpython等。具體來說
其中使用c語言開發的叫做python,在於別的語言開發的python對比時為避免歧義通常稱為CPython。同樣的,使用java開發的叫做JPython,使用.net開發的叫做IronPython。
- CPython:是用C語言實現Pyhon,是目前應用最廣泛的解釋器。最新的語言特性都是在這個上面先實現,基本包含了所有第三方庫支持
但是CPython有幾個缺陷,一是(GIL)全局鎖使Python在多線程效能上表現不佳,二是CPython無法支持JIT(即時編譯),導致其執行速度不及Java和Javascipt等語言。 - Pypy:是用Python自身實現的解釋器。針對CPython的缺點進行了各方面的改良,性能得到很大的提升。最重要的一點就是Pypy集成了JIT。但是,Pypy無法支持官方的C/Python API,導致無法使用例如Numpy,Scipy等重要的第三方庫。
那么這次看的list的實現也是看的Cpython的實現,具體鏈接可以看這兩個
頭文件的定義listobject.h和具體的實現listobject.c
總的來說,list和STL里面的vector很像,都是基於動態數組dynamic array來實現,這樣的好處呢都是方便擴容。
整體的結構定義
list的結構被定義在一個結構體中,該結構體包含有3個elment:
- PyObject_VAR_HEAD:只要頭部是PyObject_VAR_HEAD或者PyObject_HEAD的都可以看作PyObject的子類
- PyObject **ob_item:指向具體元素的指針
- Py_ssize_t allocated:allocated標明了此刻list的大小,當我們使用len()方法的時候,該方法獲取list的size,以O(1)的時間復雜度返回該值

初始化list
初始化list的時候,為了后續追加元素的方便呢,一般都會初始化一個size大小的動態數組

append
假設我們append一個新的element

一直append就會追加,指針像后移動就ok

當list滿了的時候就需要動態擴容數組,一般是擴容為原來的2倍大小

insert
insert操作在上圖可以看出一些端倪,比如我們insert(1,5),即在第一個位置插入5的時候
這個時間復雜度是O(n)的一個復雜度,因為它需要一個個的修改內存地址中對應的地址指向的值
pop
pop操作的時間負責度也是O(n),pop一般是pop最后面的元素,同樣也需要O(n)的一個時間復雜度

同時,pop之后會調用list_resize函數,如果新的list大小小於原來的一半的話,這時候就會收縮列表

remove
remove操作的時間復雜度也是O(n),移除元素,修改原位置指針所指向的值

