def flatten_json(y): out = dict() def flatten(x, name=''): if type(x) is dict: for a in x: flatten(x[a], name + a + '.') elif type(x) is list: i = 0 for a in x: flatten(a, name + str(i) + '.') i += 1 else: out[name[:-1]] = x flatten( y ) return out def is_cardinal( x ): try: i = int(x) return True except: return False def cardinal_key_to_list(x): if type(x) is not dict: return x elif type(x) is dict and all( [is_cardinal(y) for y in x.keys() ] ): return [cardinal_key_to_list(v) for v in x.values()] elif type(x) is dict: return {k: cardinal_key_to_list(v) for k, v in x.items()} def unflatten_json(y): output = dict() for key, value in y.items(): parts = key.split(".") d = output for j, part in enumerate(parts[:-1]): # parts[:-1] = all terms but last if part not in d: d[part] = dict() d = d[part] d[parts[-1]] = value return cardinal_key_to_list(output) if __name__ == '__main__': from pprint import pprint import json in1 = {"responsibleParty": [ { "email": "data@grandlyon.com", "role": "custodian", "address": "20 rue du Lac, CS 33569, Lyon cedex 03, 69505, France", "individualName": "Géomatique et données métropolitaines", "logo": "https://download.data.grandlyon.com/catalogue/images/harvesting/GrandLyon.gif", "appliesTo": ["resource1", "resource2"], "organisationName": "Metropole de Lyon / Direction Innovation Numérique et Systèmes d'Information (DINSI)" }, { "email": "data@grandlyon.com", "role": "custodian", "address": "une autre adresse", "individualName": "Géomatique et données métropolitaines", "logo": "https://download.data.grandlyon.com/catalogue/images/harvesting/GrandLyon.gif", "appliesTo": "metadata", "organisationName": "Metropole de Lyon / Direction Innovation Numérique et Systèmes d'Information (DINSI)" } ]} #in1 = dict(in1) flattened_json = flatten_json(in1) unflattened_json = unflatten_json(flattened_json) print('ORIGINAL') pprint(in1) print('') print('FLATTENED') pprint(flattened_json) print('') print('UNFLATTENED') pprint(unflattened_json) assert json.dumps(in1, sort_keys=True) == json.dumps(unflatten_json(flatten_json(in1)), sort_keys=True) exit(0) print(' ') with open('flatten_original.json', 'w') as fp: json.dump(in1, fp, sort_keys=True) with open('flatten_processed.json', 'w') as fp: json.dump(unflatten_json(flatten_json(in1)), fp, sort_keys=True) print(' ') pprint(json.dumps(unflatten_json(flatten_json(in1)), sort_keys=True))