python: agregando un diccionario a una lista; veo un comportamiento similar a un puntero

85

Intenté lo siguiente en el intérprete de Python:

>>>
>>> a = []
>>> b = {1:'one'}
>>> a.append(b)
>>> a
[{1: 'one'}]
>>> b[1] = 'ONE'
>>> a
[{1: 'ONE'}]
>>>

Aquí, después de agregar el diccionario 'b' a la lista 'a', estoy cambiando el valor correspondiente a la clave 1 en el diccionario 'a'. De alguna manera, este cambio también se refleja en la lista. Cuando agrego un diccionario a una lista, ¿no estoy agregando simplemente el valor de dictionary? Parece que he agregado un puntero al diccionario a la lista y, por lo tanto, los cambios en el diccionario también se reflejan en la lista.

No quiero que el cambio se refleje en la lista. ¿Cómo lo hago?

¡Gracias por tu tiempo!

neo29
fuente
Chéjov No es el diccionario 'b' , es el diccionario b o el diccionario del nombre 'b' . Por cierto, escribiste con error: "Estoy cambiando el valor correspondiente a la clave 1 en el diccionario 'a'" No, en el diccionario b. Con respecto a su asombro: una lista no contiene valores, contiene objetos, ya que todo es objeto en Python. O más exactamente, una lista contiene referencias a los objetos.
eyquem
Chejov También debería ver esta pregunta: ( stackoverflow.com/questions/5242933/… )
eyquem
@eyquem gracias por tu comentario. Estaba publicando esto a toda prisa. Mis disculpas.
neo29
Chéjov No fue un reproche, fue solo información. Por cierto, si mi respuesta es algo útil, se puede votar a favor. Además, puede elegir "aceptar" una respuesta entre las respuestas, al hacer clic en la franja en forma de cheurón debajo del contador de puntos a la izquierda de una respuesta, obtendrá 25 puntos. O puede optar por no aceptar ninguna pregunta.
eyquem

Respuestas:

140

Tiene razón en que su lista contiene una referencia al diccionario original.

a.append(b.copy()) debería hacer el truco.

Tenga en cuenta que esto hace una copia superficial. Una alternativa es usar copy.deepcopy(b), lo que hace una copia profunda.

NPE
fuente
6
¡increíble! Estuve bloqueado durante mucho tiempo en esto
Yasin
2
esto me voló la cabeza durante aproximadamente media hora hasta que me di por vencido y decidí revisar la pila.
FlyingZebra1
35

También con dict

a = []
b = {1:'one'}

a.append(dict(b))
print a
b[1]='iuqsdgf'
print a

resultado

[{1: 'one'}]
[{1: 'one'}]
eyquem
fuente
No estoy seguro si es lo suficientemente rápido como copy (), pero parece ser más rápido que deepcopy (). Tal vez con un esquema de diccionario complicado estará cerca de deepcopy () porque dict () crea un nuevo diccionario.
selotec