[Python核心技术与实战学习] 05 列表和元组的内部实现

 

列表和元组的内部实现

列表

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 的具体结构如下:

#ifndef Py_LIMITED_API
typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;
} PyListObject;
#endif

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

可以看到源码注释中 ob_item contains space for 'allocated' elements. The number currently in use is ob_size. 那么 allocated 与列表实际空间大小是有区别。列表实际空间大小, 是指 len(list) 返回的结果,也就是源码注释中ob_size, 表示这个列表总共存储了多少个元素。

实际情况下, 为了优化存储结构, 避免每次增加元素都要重新分配内存, 列表预分配的空间 allocated 往往会大于ob_size,所以它们的关系如同注释所示 len(list) == ob_size<= allocated。如果当前列表分配的空间已满(即 allocated == len(list)) , 则会向系统请求更大的内存空间, 并把原来的元素全部拷⻉过去。

元组

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 的具体结构如下:


#ifndef Py_LIMITED_API
typedef struct {
    PyObject_VAR_HEAD
    PyObject *ob_item[1];

    /* ob_item contains space for 'ob_size' elements.
     * Items must normally not be NULL, except during construction when
     * the tuple is not yet visible outside the function that builds it.
     */
} PyTupleObject;
#endif

注意注释的说明,其空间大小固定它依然也是一个array

参考资料:

极客时间 Python核心技术与实战学习

Python核心技术与实战(极客时间)链接:
http://gk.link/a/103Sv


GitHub链接:
https://github.com/lichangke/LeetCode

知乎个人首页:
https://www.zhihu.com/people/lichangke/

简书个人首页:
https://www.jianshu.com/u/3e95c7555dc7

个人Blog:
https://lichangke.github.io/

欢迎大家来一起交流学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值