0

I have a list that represents the layers in a dict:

layers = ('layer1', 'layer2', 'layer3')

I want to dynamically create a dictionary out of this that looks like this:

data = {'layer1': {'layer2': {'layer3': ...}}}

I want to be able to insert a value at the position of the three dots. I also want to be able to dynamically access this value using the layers list.

gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • possible duplicate of [Access python nested dictionary items via a list of keys](http://stackoverflow.com/questions/14692690/access-python-nested-dictionary-items-via-a-list-of-keys) and [list indices must be integers python nested dictionaries](http://stackoverflow.com/q/17503150) – Martijn Pieters Nov 12 '13 at 18:36

2 Answers2

0

So as I was typing this question I began to form an idea of how to do this, and then I got it. So to share my knowledge to whoever might ever need it, here it is. If you know better ways, your welcome to post different solutions!

def create_deep_dict(value, layers):

    data = {}
    layer = layers[0]

    if layers[1:]:
        data[layer] = create_deep_dict(value, layers[1:])
    else:
        data[layer] = value

    return data

def deep_dict_value(data, layers):

    layer = layers[0]

    if layers[1:]:
        return deep_dict_value(data[layer], layers[1:])
    else:
        return data[layer]

So if you use these functions like this:

layers = ['layer1', 'layer2', 'layer3']

print 'create deep dict:'
data = create_deep_dict(layers, 'hello')
print data

print '\nretrieve value from deep dict:'
print deep_dict_value(layers, data)

It will output:

create deep dict:
{'layer1': {'layer2': {'layer3': 'hello'}}}

retrieve value from deep dict:
hello
gitaarik
  • 42,736
  • 12
  • 98
  • 105
0

So I made an alternative solution that uses for loops instead of calling the function recursively. I benchmarked both approaches and the loop method turns out to be way faster as you increase the amount of layers and function calls.

def create_deep_dict(value, layers):

    orig_data = {}
    data = orig_data
    last_layer = layers[-1]

    for layer in layers[:-1]:
        data[layer] = {}
        data = data[layer]

    data[last_layer] = value

    return orig_data

def deep_dict_value(data, layers):

    for layer in layers:
        data = data[layer]

    return data
gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • This would be because there are no extra function calls and contexts on the stack, nor sublists layers[:-1], layers[:-2] and so on. A language with tail call optimization and immutable lists (like Haskell) may remove the difference, but expressed like this the faster version is also more readable. – Yann Vernier Nov 13 '13 at 12:47