Home > OS >  Flatten/merge a list of dictionaries in python
Flatten/merge a list of dictionaries in python

Time:08-19

I have a list of dictionaries:

data = [{'average': 2, 'day': '2022-01-01'},
        {'average': 3, 'day': '2022-01-02'},
        {'average': 5, 'day': '2022-01-03'},
        {'sum': 8, 'day': '2022-01-01'},
        {'sum': 15, 'day': '2022-01-02'},
        {'sum': 9, 'day': '2022-01-03'},
        {'total_value': 19, 'day': '2022-01-01'},
        {'total_value': 99, 'day': '2022-01-02'},
        {'total_value': 15, 'day': '2022-01-03'}]

I want my output as:

output = [{'average': 2, 'sum': 8, 'total_value': 19, 'day': '2022-01-01'},
          {'average': 3, 'sum': 15, 'total_value': 99, 'day': '2022-01-02'},
          {'average': 5, 'sum': 9, 'total_value': 15, 'day': '2022-01-03'}]

The output puts the values together based off their date. My approaches so far have been to try and separate everything out into different dictionaries (date_dict, sum_dict, etc.) and then bringing them all together, but that doesn't seem to work and is extremely sloppy.

CodePudding user response:

You could iterate over data and create a dictionary using day as key:

data = [{'average': 2, 'day': '2022-01-01'},
    {'average': 3, 'day': '2022-01-02'},
    {'average': 5, 'day': '2022-01-03'},
    {'sum': 8, 'day': '2022-01-01'},
    {'sum': 15, 'day': '2022-01-02'},
    {'sum': 9, 'day': '2022-01-03'},
    {'total_value': 19, 'day': '2022-01-01'},
    {'total_value': 99, 'day': '2022-01-02'},
    {'total_value': 15, 'day': '2022-01-03'}]

output = {}

for item in data:
    if item['day'] not in output:
        output[item['day']] = item
    else:
        output[item['day']].update(item)

print(list(output.values()))

Out:

[
    {'average': 2, 'day': '2022-01-01', 'sum': 8, 'total_value': 19},
    {'average': 3, 'day': '2022-01-02', 'sum': 15, 'total_value': 99}, 
    {'average': 5, 'day': '2022-01-03', 'sum': 9, 'total_value': 15}
]

CodePudding user response:

Had a bit of fun and made it with dict/list comprehension. Check out that neat | operator in python 3.9 :-)

Python <3.9

from collections import ChainMap
data_grouped_by_day  = {
    day : dict(ChainMap(*[d for d in data if d["day"] == day ]))
    for day in {d["day"] for d in data }
}
for day, group_data in data_grouped_by_day.items():
    group_data.update(day=day)
result = list(data_grouped_by_day.values())

Python 3.9

from collections import ChainMap
result = [
    dict(ChainMap(*[d for d in data if d["day"] == day ])) | {"day" : day}
    for day in {d["day"] for d in data}
]

The output in both cases is (keys order may vary)

[{'total_value': 99, 'day': '2022-01-02', 'sum': 15, 'average': 3},
 {'total_value': 15, 'day': '2022-01-03', 'sum': 9, 'average': 5},
 {'total_value': 19, 'day': '2022-01-01', 'sum': 8, 'average': 2}]
  • Related