Python-列表和元组的内部实现

Python 3.7 的 list 源码

listobject.h:

  https://github.com/python/cpython/blob/949fe976d5c62ae63ed505ecf729f815d0baccfc/Include/listobject.h#L23

listobject.c:

  https://github.com/python/cpython/blob/3d75bd15ac82575967db367c517d7e6e703a6de3/Objects/listobject.c#L33

 

list的具体结构:

Python-列表和元组的内部实现

 

 

可以看到,list 本质上是一个 over-allocate 的 array。其中,ob_item是一个指针列表,里面的每一个指针都指向列表的元素。而allocated则存储了这个列表已经被分配的空间大小

需要注意的是,allocated与列表实际空间大小的区别。列表实际空间大小,是指len(list) 返回的结果,即上述代码注释中的ob_size,表示这个列表总共存储了多少个元素。实际情况下,为了优化存储结构,避免每次增加元素都要重新分配内存,列表预分配的空间 allocated 往往会大于 ob_size(详见正文中的例子)。

所以,它们的关系为:allocated >= len(list) = ob_size。

如果当前列表分配的空间已满(即 allocated == len(list)),则会向系统请求更大的内存空间,并把原来的元素全部拷贝过去。列表每次分配空间的大小,遵循下面的模式:

0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...

 

Python 3.7 的 tuple 源码

tupleobject.h:

  https://github.com/python/cpython/blob/3d75bd15ac82575967db367c517d7e6e703a6de3/Include/tupleobject.h#L25

tupleobject.c:

  https://github.com/python/cpython/blob/3d75bd15ac82575967db367c517d7e6e703a6de3/Objects/tupleobject.c#L16

同样的,下面为 tuple 的具体结构:

Python-列表和元组的内部实现

 tuple和list相似,本质也是一个array,但是空间大小固定。不同于一般array,python的tuple做了许多优化,来提升程序中的效率。

举个例子,当tuple的大小不超过20时,python就会把它缓存在内部的一个free list中。这样,如果你以后需要再去创建同样的tuple,Python 就可以直接从缓存中载入,提高了程序运行效率。

 

上一篇:python数据类型强制转换实例详解


下一篇:python-元组