From what little I know, + op for lists only requires the 2nd operand to be iterable, which \"ha\" clearly is.
In code:
>>> x = []
>>>
Using +=
with a list is like calling extend
, not +
.
extend
with an iterable.+
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 ...