I need to convert a nested dictionary like:
log={
'hKtN': {
'edit_field': ['id','coord'],
'ids': {
'4A': {
'update_type': 'delete'
},
'1A': {
'update_type': '',
'update_detail': []
},
'2A': {
'update_type': 'edit',
'update_detail': ['0913','0914']
}
}
}
}
in a list of list:
table = [ ['hKtN',['id','coord'],'4A','delete',''],
['hKtN',['id','coord'],'1A','','']
['hKtN',['id','coord'],'2A','edit',['0913','0914']]
]
from which I'll build a table like:
logId | edit_field | ids | update_type | update_detail
--------------------------------------------------------------
hKtN | ['id','coord'] | 4A | delete |
hKtN | ['id','coord'] | 1A | |
hKtN | ['id','coord'] | 2A | edit |['0913','0914']
I cannot use Pandas. What's the most pythonic way to do this?
EDIT @Ajax1234's code works well but it's very complicated und use Pandas to build the table.If can help I'd build a more simple log dictionary like:
log2={
'logId': 'hKtN',
'edit_field': [
'id',
'coord'
],
'ids': {
'4A': {
'update_type': 'delete'
},
'1A': {
'update_type': '',
'update_detail': [
]
},
'2A': {
'update_type': 'edit',
'update_detail': [
'0913',
'0914'
]
}
}
}
CodePudding user response:
You can use a recursive generator function:
import itertools as it
log = {'hKtN': {'edit_field': ['id', 'coord'], 'ids': {'4A': {'update_type': 'delete'}, '1A': {'update_type': '', 'update_detail': []}, '2A': {'update_type': 'edit', 'update_detail': ['0913', '0914']}}}}
def flatten(d, c = [], k = 'logId'):
a, b, m = [*c], [], []
for x, y in d.items():
if k in ['logId', 'ids']:
m.append((k, x))
if not isinstance(y, dict):
a.append((x, y))
else:
b.append((x, y))
if not b:
yield from ([a] if not m else [[*a, j] for j in m])
else:
yield from [i for (x, y), j in it.zip_longest(b, m)
for i in flatten(y, c = a if j is None else [*a, j], k = x)]
tbl = [dict(i) for i in flatten(log)]
print(tbl)
Output:
[{'logId': 'hKtN', 'edit_field': ['id', 'coord'], 'ids': '4A', 'update_type': 'delete'}, {'logId': 'hKtN', 'edit_field': ['id', 'coord'], 'ids': '1A', 'update_type': '', 'update_detail': []}, {'logId': 'hKtN', 'edit_field': ['id', 'coord'], 'ids': '2A', 'update_type': 'edit', 'update_detail': ['0913', '0914']}]
CodePudding user response:
I would start with:
import pandas as pd
df = pd.json_normalize(log)
This is more simple and does this job.