Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translate a table to a hierarchical dictionary?

I have a table of the form:

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)

I'd like to work with it in python as a dictionary, of form:

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':[] }
    }
}

So that H[A][B][C] yields a particular unique list of values. For small dictionaries, I might just define the structure in advance as above, but I am looking for an efficient way to iterate over the table and build a dictionary, without specifying the dictionary keys ahead of time.

like image 982
Chris Cox Avatar asked Apr 17 '12 14:04

Chris Cox


3 Answers

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)
like image 200
Steve Mayne Avatar answered Sep 22 '22 10:09

Steve Mayne


If you ever only access H[A][B][C] (that is, never H[A] oder H[A][B] alone), I'd suggest a IMO cleaner solution: Use Tuples as defaultdict Index:

from collections import defaultdict
h = defaultdict(list)
for a, b, c, value in input:
    h[a, b, c].append(value)
like image 34
ch3ka Avatar answered Sep 23 '22 10:09

ch3ka


d = {}
for (a, b, c, value) in your_table_of_tuples:
   d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value)
like image 33
vartec Avatar answered Sep 23 '22 10:09

vartec