Home > Software design >  Convert Python nested dictionary to table or list of list (without Pandas) [closed]
Convert Python nested dictionary to table or list of list (without Pandas) [closed]

Time:09-17

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.

  • Related