¿Por qué .append() afecta a todos los elementos de una lista de listas?

Resuelto litturt asked hace 13 años • 3 respuestas

Creo una lista de listas y quiero agregar elementos a las listas individuales, pero cuando intento agregarlos a una de las listas ( a[0].append(2)), el elemento se agrega a todas las listas.

a = []
b = [1]

a.append(b)
a.append(b)

a[0].append(2)
a[1].append(3)
print(a)

Da:[[1, 2, 3], [1, 2, 3]]

Mientras que yo esperaría:[[1, 2], [1, 3]]

Cambiar la forma en que construyo la lista inicial de listas, haciendo bun int en lugar de una lista y colocando los corchetes dentro .append(), me da el resultado deseado:

a = []
b = 1

a.append([b])
a.append([b])

a[0].append(2)
a[1].append(3)
print(a)

Da:[[1, 2], [1, 3]]

¿Pero por qué? No es intuitivo que el resultado deba ser diferente. Sé que esto tiene que ver con que haya múltiples referencias a la misma lista , pero no veo dónde está sucediendo eso.

litturt avatar Jun 15 '11 22:06 litturt
Aceptado

Es porque la lista contiene referencias a objetos. Tu lista no contiene [[1 2 3] [1 2 3]], lo es [<reference to b> <reference to b>].

Cuando cambia el objeto (agregando algo a b), está cambiando el objeto en sí, no la lista que contiene el objeto.

Para obtener el efecto que desea, su lista adebe contener copias de ben lugar de referencias a b. Para copiar una lista puedes usar el rango [:]. Por ejemplo:

>>> a = []
>>> b = [1]
>>> a.append(b[:])
>>> a.append(b[:])
>>> a[0].append(2)
>>> a[1].append(3)
>>> print a
[[1, 2], [1, 3]]
Bryan Oakley avatar Jun 15 '2011 15:06 Bryan Oakley

La clave es esta parte:

a.append(b)
a.append(b)

Está agregando la misma lista dos veces, por lo que ambas a[0]y a[1]son referencias a la misma lista.

En su segundo ejemplo, está creando nuevas listas cada vez que llama a append like a.append([b]), por lo que son objetos separados que se inicializan con el mismo valor flotante.

Gavin H avatar Jun 15 '2011 15:06 Gavin H

Para hacer una copia superficial de una lista, el modismo es

a.append(b[:])

que cuando se duplica hará que a tenga dos copias nuevas de la lista bque no le darán el error de alias que informa.

msw avatar Jun 15 '2011 15:06 msw