I have a flattened dictionary which I want to make into a nested one, of the form
flat = {\'X_a_one\': 10,
\'X_a_two\': 20,
\'X_b_one\': 10,
Here's one way using collections.defaultdict, borrowing heavily from this previous answer. There are 3 steps:
defaultdict of defaultdict objects.flat input dictionary.defaultdict result according to the structure derived from splitting keys by _, using getFromDict to iterate the result dictionary.This is a complete example:
from collections import defaultdict
from functools import reduce
from operator import getitem
def getFromDict(dataDict, mapList):
"""Iterate nested dictionary"""
return reduce(getitem, mapList, dataDict)
# instantiate nested defaultdict of defaultdicts
tree = lambda: defaultdict(tree)
d = tree()
# iterate input dictionary
for k, v in flat.items():
*keys, final_key = k.split('_')
getFromDict(d, keys)[final_key] = v
{'X': {'a': {'one': 10, 'two': 20}, 'b': {'one': 10, 'two': 20}},
'Y': {'a': {'one': 10, 'two': 20}, 'b': {'one': 10, 'two': 20}}}
As a final step, you can convert your defaultdict to a regular dict, though usually this step is not necessary.
def default_to_regular_dict(d):
"""Convert nested defaultdict to regular dict of dicts."""
if isinstance(d, defaultdict):
d = {k: default_to_regular_dict(v) for k, v in d.items()}
return d
# convert back to regular dict
res = default_to_regular_dict(d)