Home > Software engineering >  Python: Creating nested dictionaries, using keys stored in a list
Python: Creating nested dictionaries, using keys stored in a list

Time:04-21

EDIT:

I forgot to mention that there are other dictionaries and lists, and the solutions suggested so far work very well for my example, but not if I want to add more dictionaries using different paths/lists.

For example:

d1 = {"firstKey":"Value_1"}
d2 = {"secondKey":"Value_2"}
d3 = {"thirdKey":"Value_3"}

p1 = ["level_1a", "level_1b", "level_1c"]
p2 = ["level_1a", "level_1d", "level_1e"]
p2 = ["level_2a", "level_2b"]

I would need to add/merge all 3 dictionaries d1, d2, d3 (and more eventually) in the same "master" dictionary, nested under all keys listed in p1, p2 and p3. Note that if a key is shared (for example "level_1a"), the existing key needs to be used, not creating a new one.

The final dictionary obtained from the three lists (and more eventually, this is just an example) should look like this:

{
    "level_1a":{
        "level_1b":{"level_1c":{"firstKey":"Value_1"}},
        "level_1d":{"level_1e":{"secondKey":"Value_2"}}
    },
    "level_2a":
        {"level_2b":{"thirdKey":"Value_3"}}
}

ORIGINAL POST:

I have a simple dictionary that I need to nest deep inside another dictionary, and the keys are stored in a list (in reversed order).

My basic dictionary looks like this: {"firstKey":"Value_1"}

The list of keys looks like this: ["level_1a", "level_1b", "level_1c"]

This is the results that I'm trying to produce:

{
 "level_1a":{
        "level_1b":{
               "level_1c":
                          {"firstKey":"Value_1"}
                   }
            }
}

This is the code that I tried, it seems like my loop keeps on adding elements instead of replacing them...

masterDict = {}

d1 = {"firstKey":"Value_1"}
p1 = ["level_1a", "level_1b", "level_1c"]
tempDict = d1.copy()

for level in reversed(p1):
    print(level)
    tempDict[level] = tempDict
    print(f'TempDict = {tempDict}')
    print('-=-=-=-')

This is what my code outputs:

level_1c
TempDict = {'firstKey': 'Value_1', 'level_1c': {...}}
-=-=-=-
level_1b
TempDict = {'firstKey': 'Value_1', 'level_1c': {...}, 'level_1b': {...}}
-=-=-=-
level_1a
TempDict = {'firstKey': 'Value_1', 'level_1c': {...}, 'level_1b': {...}, 'level_1a': {...}}
-=-=-=-

Is there a way to nest that simple dictionary only one time, using the keys in the list (and the previous dictionary becomes the new value for the keys)?

Thanks very much in advance!

CodePudding user response:

This can be done using a placeholder variable and a loop. Then just updating the placeholder with the dict:

current = master_dict = {}
data = {"firstKey":"Value_1"}
keys = ["level_1a", "level_1b", "level_1c"]

for key in keys:
    current[key] = current = {}
current.update(data)

>>> master_dict
{'level_1a': {'level_1b': {'level_1c': {'firstKey': 'Value_1'}}}}

CodePudding user response:

One option is to use dict.setdefault recursively:

def build_nested(ps, ds, d_out={}):

    def nested(p, d_in, d_out):
        if len(p)==1:
            d_out[p[0]] = d_in
        else:
            nested(p[1:], d_in, d_out.setdefault(p[0], {}))

    for p, d in zip(ps, ds):
        nested(p, d, d_out)
       
    return d_out

tmp = build_nested([p1,p3], [d1,d3])
out = build_nested([p2],[d2], tmp)

Output:

{'level_1a': {'level_1b': {'level_1c': {'firstKey': 'Value_1'}},
  'level_1d': {'level_1e': {'secondKey': 'Value_2'}}},
 'level_2a': {'level_2b': {'thirdKey': 'Value_3'}}}
  • Related