Hatox Hatox - 1 month ago 9
Python Question

Creating a nested dict out of a list with unknown length

I'm trying to get a method that gets 3 lists and turns them into a nested dict.

The first and the second list can have any amount of entries > 0.
The values list always has

len(firstlist) * len(secondlist)
entries.

For example:

givenlist1 = ["First", "Second"]
givenlist2 = ["A.B.D", "A.Y.Z", "A.B.E"]
Values = ["10", "2", "3", "4", "1", "3"]


Should return a dict like this:

{'First': {'A': {'B': {'D': '10', 'E': '3'}, 'Y': {'Z': '2'}}},
'Second': {'A': {'B': {'D': '4', 'E': '3'}, 'Y': {'Z': '1'}}}}


I tried a lot with
.update
but I just can't get an idea how to do it with a variable amount of entries in the second list.

Answer

You can use itertools.product to get the required combinations of the entries in givenlist1 and givenlist2, and use zip to associate them with the corresponding items from values. Then you need to .split the individual letter keys from the letters in the givenlist2 items to get the nested keys, creating new dicts as necessary.

from itertools import product
from pprint import pprint

givenlist1 = ["First", "Second"]
givenlist2 = ["A.B.D", "A.Y.Z", "A.B.E"]
values = ["10", "2", "3", "4", "1", "3"]

result = {k1: {} for k1 in givenlist1}

for (k1, k2), v in zip(product(givenlist1, givenlist2), values):
    d = result[k1]
    keys = k2.split('.')
    for k in keys[:-1]:
        d = d.setdefault(k, {})
    d[keys[-1]] = v

pprint(result)

output

{'First': {'A': {'B': {'D': '10', 'E': '3'}, 'Y': {'Z': '2'}}},
 'Second': {'A': {'B': {'D': '4', 'E': '3'}, 'Y': {'Z': '1'}}}}

Here's a less compact but possibly more readable way to write the inner for loop:

for k in keys[:-1]:
    if k not in d:
        d[k] = {}
    d = d[k]