Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any elegant way to build a multi-level dictionary in python?

I would like to build a multi-level dictionary such like:

A = { 
    'a': {
        'A': {
            '1': {}, 
            '2': {}, 
        },  
        'B': {
            '1': {}, 
            '2': {}, 
        },  
    },  
    'b': {
        'A': {
            '1': {}, 
            '2': {}, 
        },  
        'B': {
            '1': {}, 
            '2': {}, 
        },  
    },  
}

My question is that whether it existed a function that I can build the above diction by:

D = function(['a', 'b'], ['A', 'B'], ['1', '2'], {})
like image 846
waitingkuo Avatar asked Feb 18 '13 10:02

waitingkuo


2 Answers

This uses the copy function to allow you specify a different leaf node. Otherwise all the leaves will point to the same dictionary.

from copy import copy

def multidict(*args):
    if len(args) == 1:
        return copy(args[0])
    out = {}
    for x in args[0]:
        out[x] = multidict(*args[1:])
    return out

print multidict(['a', 'b'], ['A', 'B'], ['1', '2'], {})
like image 144
matt Avatar answered Nov 12 '22 02:11

matt


def multi(*args):
    if len(args) > 1:
        return {arg:multi(*args[1:]) for arg in args[0]}
    else:
        return args[0]

multi(['a', 'b'], ['A', 'B'], ['1', '2'], {})

returns

{'a': {'A': {'1': {}, '2': {}}, 'B': {'1': {}, '2': {}}},
 'b': {'A': {'1': {}, '2': {}}, 'B': {'1': {}, '2': {}}}}

EDIT: In my solution, the last argument {} will be copied into every leaf of the output as a reference to the same dictionary. If this is a problem (replacing it with an immutable object, such as float, integer or string is a different thing), use the copy.copy idea of @matt.

like image 25
eumiro Avatar answered Nov 12 '22 04:11

eumiro