16

Ho problemi a capire le comprensibili nested dictionary in Python 3. Il risultato che sto ottenendo dall'esempio seguente restituisce la struttura corretta senza errori, ma include solo una delle chiavi interne: value pair. Non ho trovato un esempio di comprensione di un dizionario annidato come questo; Googling "nested dictionary understanding python" mostra gli esempi legacy, le interpretazioni non annidate o le risposte risolte utilizzando un approccio diverso. Posso usare la sintassi sbagliata.Comprensione nested dizionario python

Esempio:

data = {outer_k: {inner_k: myfunc(inner_v)} for outer_k, outer_v in outer_dict.items() for inner_k, inner_v in outer_v.items()} 

Questo esempio dovrebbe restituire il dizionario originale, ma con il valore interno modificato da myfunc.

Struttura del dizionario outer_dict, così come il risultato:

{outer_k: {inner_k: inner_v, ...}, ...} 

risposta

20

{inner_k: myfunc(inner_v)} non è una comprensione dizionario. È solo un dizionario.

Probabilmente siete alla ricerca di qualcosa di simile a questo, invece:

data = {outer_k: {inner_k: myfunc(inner_v) for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in outer_dict.items()} 

Per motivi di leggibilità, non nidificano comprehensions dizionario e list comprehensions troppo.

+1

Grazie mille - se questo aiuta qualcuno, ecco un punto che mi ha confuso: la soluzione di Blender ha due modifiche dal mio ex: una parentesi spostata, e mettere il "per" interno prima dell'esterno. Originariamente avevo impostato correttamente la clausola for, ma con la parentesi nel posto sbagliato, ottenevo "NameError: nome globale 'outer_v" non è definito. "Quindi lo stesso errore con' for's nella posizione errata con la parentesi nel posto corretto –

20

Aggiungendo alcuni line-break e rientro:

data = { 
    outer_k: {inner_k: myfunc(inner_v)} 
    for outer_k, outer_v in outer_dict.items() 
    for inner_k, inner_v in outer_v.items() 
} 

... rende evidente che in realtà hanno un singolo, "2-dimensionale" dict comprensione. Che cosa si vuole realmente è probabilmente:

data = { 
    outer_k: { 
     inner_k: myfunc(inner_v) 
     for inner_k, inner_v in outer_v.items() 
    } 
    for outer_k, outer_v in outer_dict.items() 
} 

(che è esattamente ciò che Blender ha suggerito nella sua risposta, con uno spazio aggiunto).

+0

Anche molto utile, cercherò di confrontarlo con l'uso di un comp dict per 1 asse all'interno di un ciclo for, nonché il modo migliore per suddividerlo per linea, esteticamente. –