Me gustaría hacer una copia profunda de una dict
en Python. Lamentablemente, el .deepcopy()
método no existe para el dict
. ¿Cómo puedo hacer eso?
>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = my_dict.deepcopy()
Traceback (most recent calll last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'deepcopy'
>>> my_copy = my_dict.copy()
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
7
La última línea debería ser 3
.
Me gustaría que las modificaciones my_dict
no afecten la instantánea my_copy
.
¿Cómo puedo hacer eso? La solución debería ser compatible con Python 3.x.
python
python-3.x
Olivier Grégoire
fuente
fuente
Respuestas:
Qué tal si:
Python 2 o 3:
fuente
copy.deepcopy
que no es seguro para subprocesos. Aprendí esto de la manera difícil. Por otro lado, dependiendo de su caso de uso,json.loads(json.dumps(d))
es seguro para subprocesos y funciona bien.json.loads
no resuelve el problema para todos los casos de uso donde losdict
atributos de Python no son serializables JSON. Puede ayudar a aquellos que solo están lidiando con estructuras de datos simples, desde una API, por ejemplo, pero no creo que sea una solución suficiente para responder completamente la pregunta del OP.dict.copy () es una función de copia superficial para la
identificación del diccionario, es una función incorporada que le da la dirección de la variable
Primero debe comprender "¿por qué está ocurriendo este problema en particular?"
La dirección de la lista presente en ambos dictados para la clave 'a' apunta a la misma ubicación.
Por lo tanto, cuando cambia el valor de la lista en my_dict, la lista en my_copy también cambia.
Solución para la estructura de datos mencionada en la pregunta:
O puede usar la copia profunda como se mencionó anteriormente.
fuente
value[:]
. La solución fue para la estructura de datos particular mencionada en la pregunta en lugar de una solución universal.Python 3.x
desde copia importación copia profunda
Sin una copia profunda, no puedo eliminar el diccionario de nombres de host de mi diccionario de dominio.
Sin la copia profunda me sale el siguiente error:
... cuando trato de eliminar el elemento deseado de mi diccionario dentro de otro diccionario.
dominio es un objeto de diccionario
Ejemplo de salida: [orginal] domains = {'localdomain': {'localhost': {'all': '4000'}}}
[nuevos] dominios = {'localdomain': {}}}
Entonces, lo que está sucediendo aquí es que estoy iterando sobre una copia de un diccionario en lugar de iterar sobre el diccionario en sí. Con este método, puede eliminar elementos según sea necesario.
fuente
Me gusta y aprendí mucho de Lasse V. Karlsen. Lo modifiqué en el siguiente ejemplo, que resalta bastante bien la diferencia entre las copias de diccionario poco profundas y las copias profundas:
Ahora si cambias
y hacer
usted obtiene
fuente
Una solución más simple (en mi opinión) es crear un nuevo diccionario y actualizarlo con el contenido del anterior:
El problema con este enfoque es que puede no ser "lo suficientemente profundo". es decir, no es recursivamente profundo. suficientemente bueno para objetos simples pero no para diccionarios anidados. Aquí hay un ejemplo donde puede no ser lo suficientemente profundo:
Al usar Deepcopy () puedo eliminar el comportamiento semi-superficial, pero creo que uno debe decidir qué enfoque es el adecuado para su aplicación. En la mayoría de los casos, es posible que no le importe, pero debe tener en cuenta las posibles dificultades ... ejemplo final:
fuente
my_dict.copy()
!