If x is list, why does x += “ha” work, while x = x + “ha” throws an exception?

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 ...

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)