Usando +=
con una lista es como llamar extend
, no +
.
- Puede llamar al
extend
con un iterable.
- Solo puede usar
+
con otra lista.
Solo puedo adivinar por qué se tomó esta decisión, pero me imagino que es por motivos de rendimiento. Llamar al +
da como resultado la creación de un nuevo objeto y la copia de todos los elementos, mientras que extend
puede usar espacio libre en el objeto de la lista existente y, en algunos casos, guardar una copia.
Otro efecto secundario de esta decisión es que si escribe x += y
, otras referencias a la lista verán el cambio, pero si usa x = x + y
, entonces no lo harán. Esto se demuestra a continuación:
>>> 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']
Referencias
Python source code for list.
El código fuente de +=
:
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;
}
El código fuente para +
:
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 ...
"estoy de acuerdo" con su pregunta; este es un buen argumento contra la sobrecarga del operador para mí. – u0b34a0f6ae
Eliminé mi respuesta después de su edición, parece que se está preguntando sobre la razón detrás de no admitir + entre una lista y una iterable: mi error. Aparte de decir "Sí, ¿por qué no?", No tengo una respuesta. –
que es una rotura * major *. de manera más general, cualquier lenguaje o biblioteca que defina comportamientos diferentes para operadores de aspecto similar debería considerarse hostil al usuario. nadie en su sano juicio usaría '+' para la concatenación de cadenas: ¡esa operación no es conmutativa! –