Reputation: 415
I need help with a function to flatten a nested dictionary in the following format:
dict_test = {
"subdoc": {
"a": 1,
"b": 2,
"c": 3,
"array": [
{"name": "elmo"},
{"name": "oscar"}
]
}
}
I tried the function below, but is doesn´t flatten the nested keys inside the array element.
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 }
My current output is:
{'subdoc.a': 1,
'subdoc.b': 2,
'subdoc.c': 3,
'subdoc.array': [{'name': 'elmo'}, {'name': 'oscar'}]}
But actually I´m looking something like:
{
"subdoc.a": 1,
"subdoc.b": 2,
"subdoc.c": 3,
"subdoc.array.0.name": "elmo",
"subdoc.array.1.name": "oscar"
}
Upvotes: 0
Views: 149
Reputation: 5735
dict_test = {
"subdoc": {
"a": 1,
"b": 2,
"c": 3,
"array": [
{"name": "elmo"},
{"name": "oscar"}
]
}
}
def flatten(d):
agg = {}
def _flatten(d, prev_key=''):
if isinstance(d, list):
for i, item in enumerate(d):
new_k = '%s.%s' % (prev_key, i) if prev_key else i
_flatten(item, prev_key=new_k)
elif isinstance(d, dict):
for k, v in d.items():
new_k = '%s.%s' % (prev_key, k) if prev_key else k
_flatten(v, prev_key=new_k)
else:
agg[prev_key] = d
_flatten(d)
return agg
print(flatten(dict_test))
# gives {'subdoc.a': 1, 'subdoc.b': 2, 'subdoc.c': 3, 'subdoc.array.0.name': 'elmo', 'subdoc.array.1.name': 'oscar'}
Note: only tested for your case
Upvotes: 1