Use defaultdict from collections module, this way:
>>> import json
>>> s = '[ { "a":1, "b":2 }, { "b":3, "c":4 }, { "c":6, "a":5 } ]'
>>>
>>> dic = json.loads(s)
>>> dic
[{'a': 1, 'b': 2}, {'b': 3, 'c': 4}, {'a': 5, 'c': 6}]
>>> kys = set(k for sub_d in d for k in sub_d) #creates uniques keys of dictionary d
>>> kys
{'a', 'b', 'c'}
>>>
>>> from collections import defaultdict
>>> my_dict = defaultdict(list)
>>> for d in dic:
for k in kys:
my_dict[k].append(d.get(k, None))
>>> my_dict
defaultdict(<class 'list'>, {'a': [1, None, 5], 'b': [2, 3, None], 'c': [None, 4, 6]})
As for the other situation:
>>> s = '[ ["a","b","c"], [1,2,null], [null,3,4], [5,null,6] ]'
>>> d = json.loads(s)
>>> d
[['a', 'b', 'c'], [1, 2, None], [None, 3, 4], [5, None, 6]]
>>> my_dict = dict(zip(d[0], zip(*d[1:])))
>>> my_dict
{'a': (1, None, 5), 'b': (2, 3, None), 'c': (None, 4, 6)}
If you don't want tuples as values, then:
>>> my_dict = defaultdict(list)
>>> for k,v in zip(d[0], zip(*d[1:])):
my_dict[k].extend(v)
Finally, to group both cases into one function:
import json
from collections import defaultdict
def parse_data(data):
data = json.loads(data)
my_dict = defaultdict(list)
if isinstance(data[0], list):
for k,v in zip(data[0], zip(*data[1:])):
my_dict[k].extend(v)
elif isinstance(data[0], dict):
kys = set(k for sub_d in data for k in sub_d)
for d in data:
for k in kys:
my_dict[k].append(d.get(k, None))
return my_dict
s1 = '[ ["a","b","c"], [1,2,null], [null,3,4], [5,null,6] ]'
d1 = parse_data(s1)
s2 = '[ { "a":1, "b":2 }, { "b":3, "c":4 }, { "c":6, "a":5 } ]'
d2 = parse_data(s2)
Noneinstead ofnullright?nullis valid in json. If you calljson.loadson that string it converts it toNone. Presumably it also works the other way round.json.dumps(None) == 'null'