¿Por qué + y + = se comportan de manera diferente para las listas de Python?

En general, la diferencia entre a += b y a = a + b depende de si a es mutable :

  • Para un objeto inmutable a (como int , str o tuple ), hacen lo mismo.
  • Pero para un objeto mutable a (como su list ), la diferencia es que a += b muta a en su lugar. Esta mutación será observada por cualquiera con una referencia al mismo objeto a .

¿Por qué? El operador Python a += b funciona aproximadamente * invocando el primero de los tres métodos definidos y no devuelve NotImplemented :

  1. a = a.__iadd__(b) . Por lo general, esto muta a en su lugar y devuelve a .
  2. a = a.__add__(b) . Por lo general, esto crea un nuevo objeto y no modifica ni el original a ni b .
  3. a = b.__radd__(a) . Por lo general, esto crea un nuevo objeto y no modifica ni el original a ni b .

Por otro lado, a = a + b solo intenta los dos últimos de estos.

(* La historia completa es algo más complicada).

El punto que parece estar haciendo es que a = a + b no es lo mismo que a += b . Esto es verdad. De la documentación (6.2.1. Sentencias de asignación aumentada):

Una expresión de asignación aumentada como x + = 1 puede reescribirse como x = x +1 para lograr un efecto similar, pero no exactamente igual. En la versión aumentada, x solo se evalúa una vez. Además, cuando sea posible, la operación real se realiza in situ , lo que significa que, en lugar de crear un nuevo objeto y asignarlo al objetivo, el objeto antiguo se modifica en su lugar.

En este caso, está viendo la última diferencia: el objeto se modifica in situ (destructivamente) en lugar de crear un nuevo objeto.

mylist = mylist + [6] crea una nueva lista con el contenido de mylist y [6] y luego la asigna a mylist .

mylist += [6] es lo mismo que mylist.extend([6]) . Toma todos los elementos en [6] y los agrega a mylist .

En el primer caso, el contenido de la lista a la que mylist referencia mylist no cambia, pero la referencia es mylist . Sin embargo, la referencia mylist es una copia de la referencia a list1 , por lo que el cambio no se realiza en list1 .

En el segundo caso, la referencia a mylist no cambia, pero los contenidos sí cambian. Como mylist y mylist refieren a la misma lista, el cambio es visible después.

Para una lista 😡 + = y es equivalente a x.extend(y)

  >>> a = [1,2,3]
 >>> b = [4,5]
 >>> c = [6,7,8]
 >>> a + = b
 >>> a.extender (c)
 >>> a
 [1, 2, 3, 4, 5, 6, 7, 8] 

Somos estudiantes de informática, no estudiantes de lingüística. Estábamos acelerando la situación y rompimos la coherencia lingüística. No pensamos que a nadie le importaría. Oye, está documentado. RTFM.