При объединении двух списков с A + B
вы создаете совершенно новый список в памяти. Это означает, что ваша догадка верна: сложность O(n + m)
(где n
и m
- это длины списков), так как Python должен идти по обоим спискам, чтобы построить новый список.
Вы можете увидеть, как это происходит в функции list_concat
в source code for Python lists:
static PyObject *
list_concat(PyListObject *a, PyObject *bb)
{
/* ...code snipped... */
src = a->ob_item;
dest = np->ob_item;
for (i = 0; i < Py_SIZE(a); i++) { /* walking list a */
PyObject *v = src[i];
Py_INCREF(v);
dest[i] = v;
}
src = b->ob_item;
dest = np->ob_item + Py_SIZE(a);
for (i = 0; i < Py_SIZE(b); i++) { /* walking list b */
PyObject *v = src[i];
Py_INCREF(v);
dest[i] = v;
}
/* ...code snipped... */
Если вам не нужен новый список в памяти, это часто хорошая идея, чтобы воспользоваться тем, что списки mutable (и это где Python - умный). Использование A.extend(B)
- это O(m)
, что означает, что вы избегаете накладных расходов на список копирования a
.
Сложность операций с различными списками перечислены here в вики Python.
Добавление двух списков * будет * быть O (n + m), потому что каждый список Python реализован как массив C фиксированного размера. Когда вы добавляете два списка, вы выделяете память для нового массива и копируете каждый элемент каждого списка членов в массив. Использование append() и extend() улучшит производительность до O (m), но если вы * должны * создать третий список и сохранить исходные два, нет очевидного способа улучшить O (n + m). – dylrei