-1

I would like to reformat a list of dictionaries with different keys and different value lengths.

[{"city": "a", "country": "b", "house": "12"}, 
{"city": "z", "country": "d", "floorlevel": "3"}]

The output would ideally be:

{"city": ["a", "z"], "country": ["b", "d"], house": ["12", "missing"], "floorlevel": ["missing", "3"]}

Thank you!

eRawox
  • 19
  • 4
  • 3
    Does this answer your question? [merging Python dictionaries](https://stackoverflow.com/questions/2365921/merging-python-dictionaries) – 404pio May 12 '21 at 12:27

3 Answers3

1

Convert values to DataFrame, replace missing values (added for missing combinations) and last convert to dictionary by DataFrame.to_dict:

d = [{"city": "a", "country": "b", "house": "12"}, 
     {"city": "z", "country": "d", "floorlevel": "3"}]

out = pd.DataFrame(d).fillna('missing').to_dict(orient='list')
print(out)
{'city': ['a', 'z'], 
 'country': ['b', 'd'], 
 'house': ['12', 'missing'],
 'floorlevel': ['missing', '3']}

Pure python solution:

d = [{"city": "a", "country": "b", "house": "12"}, 
    {"city": "z", "country": "d", "floorlevel": "3"}]

#inspired by https://stackoverflow.com/a/2366681/2901002
out = {k:[d1.get(k, 'missing') for d1 in d] for k in {k for d1 in d for k in d1}}
print (out)
{'house': ['12', 'missing'], 
 'country': ['b', 'd'], 
 'floorlevel': ['missing', '3'], 
 'city': ['a', 'z']}
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
1

If you want a pure python implementation (no external libraries):

dicts = [
    {"city": "a", "country": "b", "house": "12"},
    {"city": "z", "country": "d", "floorlevel": "3"},
]

keys = set()
for d in dicts:
    keys.update(set(d.keys()))
out = {k: [] for k in keys}

for d in dicts:
    for k in keys:
        out[k].append(d.get(k, "missing"))

print(out)

Output:

{'country': ['b', 'd'], 'house': ['12', 'missing'], 'floorlevel': ['missing', '3'], 'city': ['a', 'z']}
Matteo Zanoni
  • 3,429
  • 9
  • 27
0
from collections import defaultdict
from itertools import chain

Get values common to all dictionaries:

union = set(chain.from_iterable(entry.keys() for entry in data))

Update dictionary to balance out missing keys:

expand = [{**entry, **{missing:"missing"}} 
          for entry in data 
          for missing in entry.keys() ^ union]

Create defaultdict:

final = defaultdict(list)

for entry in expand:
    for key, value in entry.items():
        final[key].append(value)

final


defaultdict(list,
            {'city': ['a', 'z'],
             'country': ['b', 'd'],
             'house': ['12', 'missing'],
             'floorlevel': ['missing', '3']})
sammywemmy
  • 27,093
  • 4
  • 17
  • 31