Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list into a nested dictionary

For example I have

x = ['a','b','c']

I need to convert it to:

y['a']['b']['c'] = ''

Is that possible?

For the background, I have a config file which contains dotted notation that points to a place in some json data. I'd like to use the dotted notation string to access that specific data in the json file. For example, in the config:

path_to_data = "user.name.first_name"

I'd like my script to recognize that as:

json_data["user"]["name"]["first_name"]

so I can get the value of the first_name field. I converted the original string into a list, and now I don't know how to convert it to a nested dict.

EDIT: There is an existing data structure that I need to apply the dict with. Let's say:

m = {'a': {'b': {'c': 'lolcat'}}}

so that

m['a']['b']['c']

gives me 'lolcat'. If I get the right dictionary structure (as some of the replies did), I would still need to apply this to the existing dictionary 'm'.

So, again, I get this from a config file:

c = 'a.b.c'

That I converted to a list, thinking this will make things easier:

x = ['a','b','c']

Now I have a json-like data structure:

m = {'a': {'b': {'c': 'lolcat'}}}

So the nested dict generated from 'x' should be able to traverse 'm' so that

m['a']['b']['c']

gets me the cat.

like image 826
Arbie Samong Avatar asked Jul 14 '11 06:07

Arbie Samong


2 Answers

li = ['a','b','c']

d = reduce(lambda x, y: {y:x}, reversed(li+['']))

print(d)
print(d['a']['b']['c'])
like image 55
Petar Ivanov Avatar answered Nov 10 '22 09:11

Petar Ivanov


I guess you also want to include a value in the end. This works for that too:

def get_value(d, l):
    if len(l) > 1:
        return get_value(d[l[0]], l[1:])
    return d[l[0]]

def add_keys(d, l, c=None):
    if len(l) > 1:
        d[l[0]] = _d = {}
        d[l[0]] = d.get(l[0], {})
        add_keys(d[l[0]], l[1:], c)
    else:
        d[l[0]] = c

def main():
    d = {}
    l1 = ['a', 'b', 'c', 'd']
    c1 = 'letters'
    l2 = [42, "42", (42,)]
    c2 = 42
    add_keys(d, l1, c1)
    print d
    add_keys(d, l2, c2)
    print d

if __name__ == '__main__':
    main()

It prints:

{'a': {'b': {'c': {'d': 'letters'}}}}
{'a': {'b': {'c': {'d': 'letters'}}}, 42: {'42': {(42,): 42}}}
letters
42

So it surely works. Recursion for the win.

like image 4
Mihai Maruseac Avatar answered Nov 10 '22 10:11

Mihai Maruseac