Reputation: 21
I have a dict with nested lists of dictionaries, as below:
{'data1': [{'data2': 'value2'},
{'data3': [{'data4': 'value4'},
{'data5': [{'data6': 'value6'}, {'data7': 'value7'}]}]}]}
I want to obtain:
{'data1': {'data2': 'value2',
'data3': {'data4': 'value4',
'data5': {'data6': 'value6', 'data7': 'value7'}}}}
So there are 2 tasks, convert single sub dicts to key:value
({'data2':'value2'}
to 'data2':'value2'
) and convert lists of dicts to nested dicts ({'data5': [{'data6':'value6'},{'data7' : 'value7'}]}
to 'data5': {'data6':'value6','data7' : 'value7'}
).
This is a deeply nested recursive dictionary with multiple levels.
I was trying something like this:
def flat(j):
if not isinstance(j, (dict, list)):
return j
if isinstance(j, dict):
p=list(j.values())
f=list(j.keys())
tipo=type(p[0]).__name__
if tipo=="str":
(Do something)
if isinstance(j, list):
return [flat(v) for v in j]
return {k: flat(v) for k, v in j.items()}
in order to flat the single dictionaries but I found the problem of deletting the sub dict and add the key:value. For sure there is another post with how to convert the list to nested dictionaries
Upvotes: 1
Views: 636
Reputation: 71451
You can use a recursive generator function:
data = {'data1': [{'data2': 'value2'}, {'data3': [{'data4': 'value4'}, {'data5': [{'data6': 'value6'}, {'data7': 'value7'}]}]}]}
def unnest(d):
if isinstance(d, list):
yield from [j for k in d for j in unnest(k)]
else:
for a, b in d.items():
yield (a, b if not isinstance(b, (list, dict)) else dict(unnest(b)))
result = dict(unnest(data))
Output:
{'data1': {'data2': 'value2', 'data3': {'data4': 'value4', 'data5': {'data6': 'value6', 'data7': 'value7'}}}}
This will work on both lists and dictionaries.
Upvotes: 1
Reputation: 260865
You can use a recursive approach and handle each value depending on whether this is a dict
, list
, or something else:
def unnest(x):
if isinstance(x, dict):
return {k: unnest(v) for k,v in x.items()}
elif isinstance(x, list):
return {k:unnest(v) for e in x for k,v in unnest(e).items()}
else:
return x
# assuming the input dictionary as "d"
unnest(d)
output:
{'data1': {'data2': 'value2',
'data3': {'data4': 'value4',
'data5': {'data6': 'value6', 'data7': 'value7'}
},
},
}
NB. the requirement here is that lists only contain dictionaries, if not you need to add a condition
Upvotes: 1