2012-04-17 11 views
5

Ho una tabella di forma:Traduci una tabella in un dizionario gerarchico?

A1, B1, C1, (value) 
A1, B1, C1, (value) 
A1, B1, C2, (value) 
A1, B2, C1, (value) 
A1, B2, C1, (value) 
A1, B2, C2, (value) 
A1, B2, C2, (value) 
A2, B1, C1, (value) 
A2, B1, C1, (value) 
A2, B1, C2, (value) 
A2, B1, C2, (value) 
A2, B2, C1, (value) 
A2, B2, C1, (value) 
A2, B2, C2, (value) 
A2, B2, C2, (value) 

mi piacerebbe lavorare con essa in Python come un dizionario, di forma:

H = { 
    'A1':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    }, 
    'A2':{ 
     'B1':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B2':{ 
      'C1':[],'C2':[],'C3':[] }, 
     'B3':{ 
      'C1':[],'C2':[],'C3':[] } 
    } 
} 

In modo che H[A][B][C] produce una particolare lista unica di valori. Per i dizionari di piccole dimensioni, potrei semplicemente definire la struttura in anticipo come sopra, ma sto cercando un modo efficace per iterare sulla tabella e creare un dizionario, senza specificare i tasti del dizionario prima del tempo.

+5

Cerchi sempre una tripla di valori A, B, C? Se è così, starai meglio con un singolo "dict" usando quelle triple come chiavi. –

risposta

8
input = [('A1', 'B1', 'C1', 'Value'), (...)] 

from collections import defaultdict 

tree = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 
#Alternatively you could use partial() rather than lambda: 
#tree = defaultdict(partial(defaultdict, partial(defaultdict, list))) 

for x, y, z, value in input: 
    tree[x][y][z].append(value) 
+1

Nota che se la tabella è un file di testo, ti consigliamo qualcosa come '' con open ("table") come file: '' '' input = [line.split() per la riga nel file] ''. –

+2

Un'alternativa all'utilizzo di lambda qui è quella di usare '' functools.partial() '': '' tree = defaultdict (partial (defaultdict, partial (defaultdict, list))) '' - Trovo che sia più chiaro, ma potrebbe solo Sii me. –

+0

@Lattyware Interessante, grazie per quello. –

2
d = {} 
for (a, b, c, value) in your_table_of_tuples: 
    d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value) 
+0

Perché usare '' setdefault() '' su un '' defaultdict''? –

+0

@Lattyware: perché no? – vartec

+0

Direi che è molto più brutto quando lo usi. –

4

Se si accede mai solo H [A] [B] [C] (che è, mai H [A] oder H [A] [B] da sola), io suggerirei un Soluzione pulente IMO: utilizza Tuples come indice predefinito:

from collections import defaultdict 
h = defaultdict(list) 
for a, b, c, value in input: 
    h[a, b, c].append(value) 
+0

Anche questa è una soluzione molto valida (ed elegante), anche se richiede che non voglia accedere ai sottotitoli separatamente. (modificato per rimuovere qualche indentazione aggiuntiva, parentesi non necessarie e PEP-8ifying i nomi delle variabili). –

+0

Grazie per aver postato questa soluzione. In questo caso, ho bisogno di accedere ai dizionari secondari, ma non l'ho specificato nella domanda. Questo sarà estremamente elegante se questo caso esiste in futuro. –