resueltos recorrer lista funciones elementos ejercicios ejemplo diccionarios diccionario dentro convertir agregar python python-3.x

recorrer - Copia profunda de un dict en python



lista dentro de un diccionario python (4)

Me gustaría hacer una copia profunda de un dict en python. Desafortunadamente, el método .deepcopy() 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 debe ser 3 .

Me gustaría que las modificaciones en my_dict no afecten la instantánea my_copy .

¿Cómo puedo hacer eso? La solución debe ser compatible con Python 3.x.


Python 3.x

desde copia importada en copia profunda

my_dict = {''one'': 1, ''two'': 2} new_dict_deepcopy = deepcopy(my_dict)

Sin la copia en profundidad, no puedo eliminar el diccionario de nombre de host dentro del diccionario de mi dominio.

Sin deepcopy me sale el siguiente error:

"RuntimeError: dictionary changed size during iteration"

... cuando intento eliminar el elemento deseado de mi diccionario dentro de otro diccionario.

import socket import xml.etree.ElementTree as ET from copy import deepcopy

dominio es un objeto de diccionario

def remove_hostname(domain, hostname): domain_copy = deepcopy(domain) for domains, hosts in domain_copy.items(): for host, port in hosts.items(): if host == hostname: del domain[domains][host] return domain

Salida de ejemplo: [original] dominios = {''dominio local'': {''localhost'': {''todos'': ''4000''}}}

[new] domains = {''localdomain'': {}}}

Entonces, lo que está sucediendo aquí es que estoy iterando sobre una copia de un diccionario en lugar de hacerlo sobre el mismo diccionario. Con este método, puedes eliminar elementos según sea necesario.


Qué tal si:

import copy d = { ... } d2 = copy.deepcopy(d)

Python 2 o 3:

Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import copy >>> my_dict = {''a'': [1, 2, 3], ''b'': [4, 5, 6]} >>> my_copy = copy.deepcopy(my_dict) >>> my_dict[''a''][2] = 7 >>> my_copy[''a''][2] 3 >>>


Una solución más simple (en mi opinión) es crear un nuevo diccionario y actualizarlo con el contenido del anterior:

my_dict={''a'':1} my_copy = {} my_copy.update( my_dict ) my_dict[''a'']=2 my_dict[''a''] Out[34]: 2 my_copy[''a''] Out[35]: 1

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 que no sea lo suficientemente profundo:

my_dict1={''b'':2} my_dict2={''c'':3} my_dict3={ ''b'': my_dict1, ''c'':my_dict2 } my_copy = {} my_copy.update( my_dict3 ) my_dict1[''b'']=''z'' my_copy Out[42]: {''b'': {''b'': ''z''}, ''c'': {''c'': 3}}

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 los posibles escollos ... ejemplo final:

import copy my_copy2 = copy.deepcopy( my_dict3 ) my_dict1[''b'']=''99'' my_copy2 Out[46]: {''b'': {''b'': ''z''}, ''c'': {''c'': 3}}


dict.copy () es una función de copia superficial para diccionario
ID es una función incorporada que le da la dirección de la variable

Primero debes entender "¿por qué está ocurriendo este problema en particular?"

In [1]: my_dict = {''a'': [1, 2, 3], ''b'': [4, 5, 6]} In [2]: my_copy = my_dict.copy() In [3]: id(my_dict) Out[3]: 140190444167808 In [4]: id(my_copy) Out[4]: 140190444170328 In [5]: id(my_copy[''a'']) Out[5]: 140190444024104 In [6]: id(my_dict[''a'']) Out[6]: 140190444024104

La dirección de la lista presente en ambos dictados para la clave ''a'' está apuntando 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:

In [7]: my_copy = {key: value[:] for key, value in my_dict.items()} In [8]: id(my_copy[''a'']) Out[8]: 140190444024176

O puedes usar deepcopy como se mencionó anteriormente.