2014-11-27 11 views
5

Ho un dizionario nidificato e voglio essere in grado di eliminare una chiave arbitraria al suo interno.Elimina dinamicamente un elemento da un dizionario nidificato

Il dizionario potrebbe essere la seguente:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 

Ma potrebbe essere di dimensione arbitraria. Il problema è che le chiavi dovrebbero essere prese da una "lista tasto" cerca, per esempio, in questo modo:

key_list = ['key1', 'key2', 'key4'] 

key_list potrebbe essere di dimensione arbitraria e presentare una delle chiavi del dizionario in esso.

A causa dei criteri di cui sopra, non posso semplicemente usare:

del D['key1']['key2']['key4'] 

perché non posso sapere in anticipo quali chiavi che key_list conterrà.

Quindi, come sarebbe un codice generico come quello basato sul contenuto di key_list, elimina l'elemento corrispondente nel dizionario D?

+0

sei sicuro circa l'ordine del tuo 'key_list' e se si desidera eliminare l'elemento corrispondente non genera' KeyError'! – Kasramvd

+0

No KeyError per me no. – PandaDeTapas

+0

Due domande che potrebbero cristallizzare il problema nella mia mente: 1) L'intento è ogni volta di rimuovere una singola coppia chiave/valore dal dizionario? 2) La sequenza in cui le chiavi appaiono in key_list è significativa? Suppongo che la seconda domanda sia molto simile a ciò che @Kasra sta chiedendo. – rchang

risposta

4

È possibile utilizzare un ciclo for per passare attraverso i valori in key_list e passare alla sub-dizionario che si desidera rimuovere la voce da:

sub = D     # Start with the full dictionary 
for i in key_list[:-1]: 
    sub = sub[i]  # Move down a level 

Alla fine, sub sarà il dizionario che vuoi modificare. Tutto quello che dovete fare ora è:

del sub[key_list[-1]] 

dal key_list[-1] è la chiave per rimuovere.

Qui di seguito è una dimostrazione:

>>> D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 
>>> key_list = ['key1', 'key2', 'key4'] 
>>> sub = D 
>>> for i in key_list[:-1]: 
...  sub = sub[i] 
... 
>>> del sub[key_list[-1]] 
>>> D 
{'key1': {'key5': 'value5', 'key2': {'key3': 'value3'}}} 
>>> 

Come potete vedere, questo è equivalente a:

>>> D={'key1':{'key2':{'key3':'value3', 'key4':'value4'}, 'key5':'value5'}} 
>>> del D['key1']['key2']['key4'] 
>>> D 
{'key1': {'key5': 'value5', 'key2': {'key3': 'value3'}}} 
>>> 

tranne che la soluzione sia dinamici (tasti senza hard-coded).

+0

Sembra funzionare alla grande! Non mi ero reso conto che sub potesse influenzare D, bella soluzione. – PandaDeTapas

0

Si può pensare ai dizionari nidificati come dizionario con chiavi multipart. Se trasformi il tuo dict, decidi tu quando eliminare un elemento. Se una parte della chiave è presente nella keylist o in qualsiasi altro criterio. Considera questo:

D={'key1':{'key2':{'key3':'value3', 'key4':'value4', 'key7':{'key8':'value8'}}, 'key5':'value5'}, 'key6': 'value6'} 

def multipart_key(d): 
    dd = {} 
    for k in d: 
     if isinstance(d[k], dict): 
      inner = multipart_key(d[k]) 
      for kk in inner: 
       dd[k+chr(124)+kk] = inner[kk] 
     else: 
      dd[k] = d[k] 
    return dd 

key_list = ['key3', 'key7'] 

DD = multipart_key(D) 
newDD = DD.copy() 

for k in DD: 
    for kk in k.split(chr(124)): 
     if kk in key_list: 
      del newDD[k] 
      break 

print(DD) 
# {'key1|key2|key3': 'value3', 'key1|key5': 'value5', 'key6': 'value6', 'key1|key2|key7|key8': 'value8', 'key1|key2|key4': 'value4'} 

print(newDD) 
# {'key1|key5': 'value5', 'key6': 'value6', 'key1|key2|key4': 'value4'} 
Problemi correlati