Ad esempio, se ho un dittico di dict o un dittico di matrici, ma desidero solo copiare "in profondità" a due livelli di profondità, esiste un modo semplice per farlo?In python come potrei fare una copia profonda di un dict ad una profondità particolare?
Mi guardavo intorno per vedere se c'era una biblioteca che potevo usare o un esempio ma non riuscivo a trovare nulla. Sono abbastanza nuovo per Python, altrimenti scriverò la subroutine per farlo da solo. Qualche idea? I frammenti di codice sarebbero apprezzati in quanto sarebbe più veloce per me capire che una semplice spiegazione su come farlo.
Grazie.
INFORMAZIONI AGGIUNTIVE:
Alcuni hanno chiedere perché vorrei fare questo, ho bisogno di una copia (non un ref come sto andando a modificare alcuni dei valori e non voglio che l'originale modificato) di alcuni degli elementi da un dict ma il dict è enorme (molti dict di dicts) e quindi non voglio far saltare in aria la mia memoria impronta
mIO CODICE FINORA
Va bene, mi arrendo su. Questo è stato più difficile di quanto mi aspettassi e non ho il tempo di capirlo. Il mio ultimo tentativo con qualche codice di debug/test.
# 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
I Non riesco a trovare un modo affidabile e coerente per determinare se l'elemento è iterabile. Ho letto il numero this post e ho cercato di capirlo, ma nessuna delle soluzioni sembrava funzionare per il mio caso di test.
Mi limiterò a copiare l'intero dict e cercherò di ottimizzare la soluzione in seguito (o meno).
Grazie ...
Quale problema speri di risolvere facendo questo? –
hai provato l'ovvio 'copy.deepcopy (x)' e 'pickle'? – zenpoy
@zenpoy Ho guardato copy.deepcopy (x) ma non sembrava in grado di limitare la sua copia ad una particolare profondità. Non pensavo di usare pickle e non sono sicuro di come avrebbe funzionato, ma il tuo suggerimento mi ha fatto pensare che forse potresti ottenere il pprint per fare la copia in quanto ti permette di specificare una profondità ??? Devo pensare a come funzionerebbe comunque. – stephenmm