[英]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)
反映了重新定位(最多) N
个sizeof(PyObject *)
个字节的对象所需的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.