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

Question:

Below is a pop() operation of Python written in C.

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. But there’s no for statement here.
It just returns v.

If pop(0), does Python move all the pointers inside the list forward one by one?

Asked By: helloworld

||

Answers:

Recall that at the C level, a list is an array of pointers to the objects contained in the list.

In the code above, it calls list_ass_slice() which literally just calls memmove() to relocate the pointers after the popped element.

From 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.

Answered By: sj95126
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.