扒一扒python的list内部

这篇文章主要总结python源码深度剖析中介绍list对象的一些内容。

本文主要介绍如下内容:

1.list的内部结构

2.list的自动扩缩容现象及原理

3.list的append、pop、insert、remove等操作的时间复杂度

4.list的深浅拷贝操作

首先看list的内部结构

list内部由PyListObject结构体表示,源码如下


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;

可见,list是一个变长对象,内部维护了一个动态数组:

ob_item:指向动态数组的指针,动态数组保存元素对象的指针

allocated:动态数组长度,即列表容量

ob_size:表示冬天数组当前保存的元素个数,即列表长度

然后看list的自动扩缩容现象及原理

现象:列表长度超过底层数组容量时,需要扩容,列表长度低于底层数组容量时,需要缩容

原理:主要依赖list_resize 方法,关键代码如下


static int
list_resize(PyListObject *self, Py_ssize_t newsize)
{
    PyObject **items;
    size_t new_allocated, num_allocated_bytes;
    Py_ssize_t allocated = self->allocated;

    /* Bypass realloc() when a previous overallocation is large enough
       to accommodate the newsize.  If the newsize falls lower than half
       the allocated size, then proceed with the realloc() to shrink the list.
    */
    if (allocated >= newsize && newsize >= (allocated >> 1)) {
        assert(self->ob_item != NULL || newsize == 0);
        Py_SIZE(self) = newsize;
        return 0;
    }

    /* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
     * Note: new_allocated won't overflow because the largest possible value
     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
     */
    new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);
    if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {
        PyErr_NoMemory();
        return -1;
    }

    if (newsize == 0)
        new_allocated = 0;
    num_allocated_bytes = new_allocated * sizeof(PyObject *);
    items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);
    if (items == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    self->ob_item = items;
    Py_SIZE(self) = newsize;
    self->allocated = new_allocated;
    return 0;
}

更多内容见
python内部的list

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
库存是指利用Python编程语言来获取或提取库存信息的过程。Python作为一种多功能的编程语言,具有强大的数据处理和网络访问功能,非常适合用来进行库存操作。 使用Python进行库存的基本步骤如下: 1. 确定目标网站:首先需要确定要取库存信息的目标网站。可以选择一些电商网站或其他在线商店的网站,这些网站通常有显示产品库存信息的页面。 2. 网络请求与页面解析:利用Python的网络请求库(例如requests)发送GET请求获取目标网页的HTML代码。然后使用HTML解析库(例如BeautifulSoup)对网页进行解析,提取目标产品的库存信息。 3. 提取库存信息:根据目标网站的HTML结构,使用合适的选择器(例如CSS选择器或XPath)从HTML代码中提取出库存信息。可以通过查找特定的HTML标签、类名或ID等来定位库存信息所在的元素,并进行解析和提取。 4. 数据处理与存储:将提取到的库存信息进行数据处理,例如去除多余的空格、格式化数据等。然后选择合适的方式将数据存储到本地文件或数据库中,方便之后的分析或使用。 5. 循环或定时更新:如果需要定期获取最新的库存信息,可以使用循环或定时任务来定期执行库存的代码。可以设置合适的时间间隔或触发条件,以确保库存信息始终保持最新。 需要注意的是,在进行库存的过程中,需要遵守网站的相关规定和法律法规,避免对目标网站造成过大的负担或侵犯其合法权益。在进行任何网络爬虫操作时,都应该尊重网站的使用条款和隐私政策,以及专有信息的知识产权。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值