Using +=
with a list is like calling extend
, not +
.
- You can call
extend
with an iterable.
- You can only use
+
with another list.
I can only guess why this decision was made, but I imagine it is for performance reasons. Calling +
results in a new object being created and all items being copied, whereas extend
can use free space in the existing list object saving a copy in some cases.
Another side-effect of this decision is that if you write x += y
other references to the list will see the change but if you use x = x + y
then they will not. This is demonstrated below:
>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x += y
>>> z
['a', 'b', 'c', 'd']
>>> x = ['a','b']
>>> y = ['c', d']
>>> z = x
>>> x = x + y
>>> z
['a', 'b']
References
Python source code for list.
Source code for +=
:
static PyObject *
list_inplace_concat(PyListObject *self, PyObject *other)
{
PyObject *result;
result = listextend(self, other);
if (result == NULL)
return result;
Py_DECREF(result);
Py_INCREF(self);
return (PyObject *)self;
}
Source code for +
:
static PyObject *
list_concat(PyListObject *a, PyObject *bb)
{
Py_ssize_t size;
Py_ssize_t i;
PyObject **src, **dest;
PyListObject *np;
if (!PyList_Check(bb)) {
PyErr_Format(PyExc_TypeError,
"can only concatenate list (not \"%.200s\") to list",
bb->ob_type->tp_name);
return NULL;
}
// etc ...