简体   繁体   English

Python 中的弹出(索引)操作如何工作?

[英]How does a pop (index) operation work in Python?

Below is a pop() operation of Python written in C.下面是C写的Python的pop()操作。

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;
}

I understand that pop(index) takes O(N) time.我知道pop(index)需要O(N)时间。 But there's no for statement here.但是这里没有for声明。 It just returns v .它只是返回v

If pop(0) , does Python move all the pointers inside the list forward one by one?如果pop(0) , Python 是否将列表内的所有指针一一向前移动?

Recall that at the C level, a list is an array of pointers to the objects contained in the list.回想一下,在 C 级别, list是指向列表中包含的对象的指针数组。

In the code above, it calls list_ass_slice() which literally just calls memmove() to relocate the pointers after the popped element.在上面的代码中,它调用list_ass_slice() ,它实际上只是调用memmove()来重新定位弹出元素之后的指针。

From Objects/listobject.c:list_ass_slice() :Objects/listobject.c:list_ass_slice()

    if (d < 0) { /* Delete -d items */
        Py_ssize_t tail;
        tail = (Py_SIZE(a) - ihigh) * sizeof(PyObject *);
        memmove(&item[ihigh+d], &item[ihigh], tail);

The O(N) is a reflection of the time it takes to relocate (up to) N objects of sizeof(PyObject *) bytes. O(N)反映了重新定位(最多) Nsizeof(PyObject *)个字节的对象所需的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM