You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中list.pop(index)工作原理解析及相关性能疑问

关于Python list.pop(0)的元素移动问题

答案是肯定的:执行pop(0)时,Python会把列表内所有后续元素的指针逐个向前移动,只是这个移动逻辑没有直接写在list_pop_impl函数里,而是封装到了list_ass_slice函数中。

结合你提供的代码具体分析:

  1. 当要删除的元素不是列表最后一个元素时(比如pop(0)),代码会调用list_ass_slice(self, index, index+1, (PyObject *)NULL),这个函数的作用是删除列表中[index, index+1)区间的单个元素。
  2. 在CPython的底层实现里,list_ass_slice处理非末尾元素删除时,会通过**内存拷贝操作(比如memmove)**把index+1位置到列表末尾的所有指针,整体向前移动一个位置。这和手动写for循环逐个移动指针的效果完全一致,时间复杂度为O(N),也对应了pop(index)(index非末尾)的O(N)时间复杂度。
  3. 只有删除最后一个元素时,代码调用的list_resize只是调整列表的长度标记,不需要移动任何元素,所以时间复杂度是O(1)。

附上你提供的list_pop_impl实现代码:

static PyObject *
list_pop_impl(PyListObject *self, Py_ssize_t index)
/*[clinic end generated code: output=6bd69dcb3f17eca8 input=b83675976f329e6f]*/
{
    PyObject *v;
    int status;

    if (Py_SIZE(self) == 0) {
        /* Special-case most common failure cause */
        PyErr_SetString(PyExc_IndexError, "pop from empty list");
        return NULL;
    }
    if (index < 0)
        index += Py_SIZE(self);
    if (!valid_index(index, Py_SIZE(self))) {
        PyErr_SetString(PyExc_IndexError, "pop index out of range");
        return NULL;
    }
    v = self->ob_item[index];
    if (index == Py_SIZE(self) - 1) {
        status = list_resize(self, Py_SIZE(self) - 1);
        if (status >= 0)
            return v; /* and v now owns the reference the list had */
        else
            return NULL;
    }
    Py_INCREF(v);
    status = list_ass_slice(self, index, index+1, (PyObject *)NULL);
    if (status < 0) {
        Py_DECREF(v);
        return NULL;
    }
    return v;
}

内容的提问来源于stack exchange,提问作者helloworld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:20:21