Reputation: 63
I have nested dictionary d
as below
d = {'id': {"a,b": {'id': {"x": {'id': None},
"y": {'id': {"a": {'id': None},
"b": {'id': None}}}}},
"c,d": {'id': {"c": {'id': None},
"d": {'id': {"x": {'id': None},
"y": {'id': None}}}}}}}
and would like unnest some levels and compress it to the following output:
{"a,b": {"x": None,
"y": {"a": None,
"b": None}},
"c,d": {"c": None,
"d": {"x": None,
"y": None}}}
Would like to unnest any nested dictionary with the key id
and replace it with the inner dictionary
My starting point is:
def unnest_dictionary(d):
for k,v in d.items():
if isinstance(v, dict):
unnest_dictionary(v)
if k=='id':
......
Not sure how to unnest it from there
Upvotes: 0
Views: 136
Reputation: 63
Here is how i ended up solving for it
I flattened the dictionary, removed the levels with id
then nested it back again
import re
d = {'id': {"a,b": {'id': {"x": {'id': None},
"y": {'id': {"a": {'id': None},
"b": {'id': None}}}}},
"c,d": {'id': {"c": {'id': None},
"d": {'id': {"x": {'id': None},
"y": {'id': None}}}}}}}
def flatten_dict(dd, separator ='_', prefix =''):
return { prefix + separator + k if prefix else k : v
for kk, vv in dd.items()
for k, v in flatten_dict(vv, separator, kk).items()
} if isinstance(dd, dict) else { prefix : dd }
def nest_dict(dict1):
result = {}
for k, v in dict1.items():
split_rec(k, v, result)
return result
def split_rec(k, v, out):
k, *rest = k.split('_', 1)
if rest:
split_rec(rest[0], v, out.setdefault(k, {}))
else:
out[k] = v
flat_d = flatten_dict(d)
for k in list(flat_d.keys()):
new_key = re.sub(r'_id|id_','',k)
flat_d[new_key] = flat_d.pop(k)
nested_d = nest_dict(flat_d)
print(nested_d)
# {'a,b': {'x': None, 'y': {'a': None, 'b': None}}, 'c,d': {'c': None, 'd': {'x': None, 'y': None}}}
Upvotes: 1