I have a nested dictionary which I want to flatten while overwriting values of duplicate keys. Example input looks like this:
{
'abc': 1,
'foo': 2
'cba': {'abc': 3, 'baz': {
'foo': 4
}}
}
The goal is to overwrite values of keys in the top level dict with a value of the same key in a lower level dict, where the key in the lowest level dict is ruling.
and the output needs to be this:
{
'abc': 3,
'foo': 4,
'cba': {'abc': 3, 'baz': {
'foo': 4
}}
}
I was trying to find a solution on SO but couldn't find one... Hopefully someone can help me out :)
CodePudding user response:
Not sure how robust this is, but I guess this is what you are looking for (credit to https://stackoverflow.com/a/6027615/5417511):
import collections
d = {
'abc': 1,
'foo': 2,
'cba': {'abc': 3, 'baz': {
'foo': 4
}}
}
def flatten(d):
items = []
for k, v in d.items():
if isinstance(v, collections.MutableMapping):
items.extend(flatten(v).items())
else:
items.append((k, v))
return dict(items)
d.update(flatten(d))
print(d)
{'abc': 3, 'foo': 4, 'cba': {'abc': 3, 'baz': {'foo': 4}}}
CodePudding user response:
The code below finds the maximum depth value for each key and then recursively updates the original input:
from collections import defaultdict
data = {'abc': 1, 'foo': 2, 'cba': {'abc': 3, 'baz': {'foo': 4}}}
def levels(d, c = 0):
for a, b in d.items():
yield from [(c, a, b)] if not isinstance(b, dict) else levels(b, c 1)
l = defaultdict(dict)
for _l, a, b in levels(data):
l[a][_l] = b
def new_d(d):
return {a:new_d(b) if isinstance(b, dict) else l[a][max(l[a])] for a, b in d.items()}
result = new_d(data)
Output:
{'abc': 3, 'foo': 4, 'cba': {'abc': 3, 'baz': {'foo': 4}}}
CodePudding user response:
you look probably for something like
ndir = { 'abc': 1, 'foo': 2, 'cba': {'abc': 3, 'baz': { 'foo': 4 }} } print(ndir) res = {} def GetContent(ndir): for k, v in ndir.items(): if isinstance(v, dict): GetContent(v) else: res[k]=v GetContent(ndir) print(res)