以下列方式在python列表中插入元素有什么区别?
myList.insert(at, myValue)
myList[at:at] = [myValue]
我已经进行了一些测试,两者的性能非常相似,但切片插件始终会产生稍微好一些的效果。我的问题是关于实施和绩效的差异,而不是行为。
答案 0 :(得分:1)
我们有相同的行为,见下文:
默认行为是在给定索引处插入项目; 更高指数的每个值都会移动一个位置到最后。
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list.insert(5, 'item')
>>> my_list
['a', 'b', 'c', 'd', 'e', 'item', 'f', 'g']
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list.insert(-3, 'item')
>>> my_list
['a', 'b', 'c', 'd', 'item', 'e', 'f', 'g']
如果列表为空,则正常附加项目。
>>> my_list = []
>>> my_list.insert(5, 'item')
>>> my_list
['item']
>>> my_list = []
>>> my_list.insert(-3, 'item')
>>> my_list
['item']
如果索引超出范围,则在索引为正数时将项目附加到末尾,如果为负数则将项目附加到开头。 没有例外。
>>> my_list = ['a', 'b']
>>> my_list.insert(5, 'item')
>>> my_list
['a', 'b', 'item']
>>> my_list = ['a', 'b']
>>> my_list.insert(-3, 'item')
>>> my_list
['item', 'a', 'b']
切片表示法具有完全相同的行为, 在一系列相同索引的情况下:
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list[5:5] = ['item']
>>> my_list
['a', 'b', 'c', 'd', 'e', 'item', 'f', 'g']
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list[-3:-3] = ['item']
>>> my_list
['a', 'b', 'c', 'd', 'item', 'e', 'f', 'g']
>>> my_list = []
>>> my_list[5:5] = ['item']
>>> my_list
['item']
>>> my_list = []
>>> my_list[-3:-3] = ['item']
>>> my_list
['item']
>>> my_list = ['a', 'b']
>>> my_list[5:5] = ['item']
>>> my_list
['a', 'b', 'item']
>>> my_list = ['a', 'b']
>>> my_list[-3:-3] = ['item']
>>> my_list
['item', 'a', 'b']
切片表示法与使用__setitem__()
对象调用slice
方法相同:
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list.__setitem__(slice(5, 5), ['item'])
>>> my_list
['a', 'b', 'c', 'd', 'e', 'item', 'f', 'g']
答案 1 :(得分:0)
实施细节
根据GitHub在https://github.com/python/cpython/blob/master/Objects/listobject.c和https://github.com/python/cpython/blob/master/Objects/listobject.c上提供的CPython实现,我们有:
.button {
display:block;
}
方法在以下函数中定义:
insert()
哪个调用static PyObject *
listinsert(PyListObject *self, PyObject *args)
{
Py_ssize_t i;
PyObject *v;
if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
return NULL;
if (ins1(self, i, v) == 0)
Py_RETURN_NONE;
return NULL;
}
函数,这里是C代码:
ins1()
切片调用由static int
ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
{
Py_ssize_t i, n = Py_SIZE(self);
PyObject **items;
if (v == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (n == PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"cannot add more objects to list");
return -1;
}
if (list_resize(self, n+1) < 0)
return -1;
if (where < 0) {
where += n;
if (where < 0)
where = 0;
}
if (where > n)
where = n;
items = self->ob_item;
for (i = n; --i >= where; )
items[i+1] = items[i];
Py_INCREF(v);
items[where] = v;
return 0;
}
函数完成:
PyList_SetSlice()
优化的实施在:
完成int
PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
if (!PyList_Check(a)) {
PyErr_BadInternalCall();
return -1;
}
return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
}
插入在以下代码中完成:
static int
list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
希望它有所帮助!