Por ejemplo, si tengo un dict de dicts o un dict de matrices pero solo deseo una copia "profunda" a una profundidad de dos niveles, ¿hay alguna manera fácil de hacerlo?En python, ¿cómo haré una copia profunda de un dict a una profundidad particular?
Estaba mirando a su alrededor para ver si había una biblioteca que podría usar o un ejemplo pero no pude encontrar nada. Soy bastante nuevo en Python o, de lo contrario, escribiría la subrutina para hacerlo yo mismo. ¿Algunas ideas? Los fragmentos de código se apreciarán, ya que sería más rápido para mí entender que solo una explicación de cómo hacerlo.
Gracias.
INFORMACIÓN ADICIONAL:
Algunos tienen preguntar por qué me gustaría hacer esto, necesito una copia (no es un ref como voy a modificar algunos de los valores y no quiero el original modificado) de algunos de los elementos de un diccionario pero el dict es enorme (muchos dict de dicts) y por lo que no tratan de destruir mi huella de memoria
CÓDIGO dE mI eN lO qUE VA
bien, me rindo arriba. Esto fue más difícil de lo que esperaba y no tengo tiempo para resolverlo. Mi último intento con un código de depuración/prueba.
# Deep copy any iteratable item to a max depth and defaults to removing the
# rest. If you want to keep the stuff past max depth as references to orig
# pass the argument else_ref=1. Ex:
# dict_copy = copy_to_depth(dict_orig, 2, else_ref=1)
def copy_to_depth(orig, depth, **kwargs):
copy = type(orig)()
for key in orig:
# Cannot find a reliable and consistent way to determine if the item
# is iterable.
#print orig[key].__class__
#if hasattr(orig[key], '__iter__'):
#if hasattr(orig[key], '__contains__'):
#if iterable(orig[key]):
#try:
if hasattr(orig[key], '__contains__'):
if depth > 0:
copy[key] = copy_to_depth(orig[key], depth - 1, **kwargs)
else:
if 'else_ref' in kwargs:
copy[key] = orig[key]
else:
copy[key] = 'PAST_MAX_DPETH_ITERABLE_REMOVED'
#except:
else:
copy[key] = orig[key]
return copy
def iterable(a):
try:
(x for x in a)
return True
except TypeError:
return False
people = {'rebecca': 34, 'dave': 'NA', 'john': 18, 'arr': [9,8,{'a':1,'b':[1,2]}], 'lvl1':
{'arr': [9,8,{'a':1,'b':[1,2]}], 'dave': 'NA', 'john': 18, 'rebecca': 34, 'lvl2':
{'arr': [9,8,{'a':1,'b':[1,2]}], 'dave': 'NA', 'john': 18, 'rebecca': 34, 'lvl3':
{'rebecca': 34, 'dave': 'NA', 'john': 18, 'arr': [9,8,{'a':1,'b':[1,2]}]}}}}
print people
ppl_cpy = copy_to_depth(people, 1)
ppl_cpy['arr'][1] = 'nine' # does not mod orig
ppl_cpy['john'] = 0 # does not mod orig
ppl_cpy['lvl1']['john'] = 1 # does not mod orig b/c copy_to_depth
ppl_cpy['arr'][3]['a'] = 'aie' # does not mod orig
#ppl_cpy['lvl1']['lvl2']['john'] = 2 # Rest cause an error
#ppl_cpy['lvl1']['lvl2']['lvl3']['john'] = 3
print people
print ppl_cpy
ppl_cpy = copy_to_depth(people, 1, else_ref=1)
ppl_cpy['john'] = 0 # does not mod orig
ppl_cpy['lvl1']['john'] = 1 # does not mod orig b/c copy_to_depth was 1
ppl_cpy['lvl1']['lvl2']['john'] = 2 # Rest Do not cause error but modifies orig
ppl_cpy['lvl1']['lvl2']['lvl3']['john'] = 3
print people
print ppl_cpy
No se puede encontrar una manera confiable y consistente de determinar si el elemento es iterable. He estado leyendo this post y tratando de resolverlo, pero ninguna de las soluciones parecía funcionar para mi caso de prueba.
Copiaré todo el dict y trataré de optimizar la solución más tarde (o no).
Gracias ...
¿Qué problema espera resolver al hacer esto? –
¿has probado el obvio 'copy.deepcopy (x)' y 'pickle'? – zenpoy
@zenpoy Miré copy.epcopy (x) pero no parecía poder limitar su copia a una profundidad particular. No pensé usar Pickle y no estoy seguro de cómo funcionaría, pero tu sugerencia me hizo pensar que tal vez podrías obtener una copia para hacer la copia, ya que te permite especificar una profundidad? Sin embargo, tengo que pensar cómo funcionaría eso. – stephenmm