基于python中的键在dicts列表上聚合值

时间:2017-08-22 23:05:05

标签: python list dictionary

我正在尝试获取2个不同列表的聚合,其中每个元素都是一个包含2个条目,月份和值的字典。

所以第一个列表如下所示:

[{
    'patient_notes': 5,
    'month': datetime.date(2017, 1, 1)
}, {
    'patient_notes': 5,
    'month': datetime.date(2017, 2, 1)
}, {
    'patient_notes': 5,
    'month': datetime.date(2017, 5, 1)
}, {
    'patient_notes': 5,
    'month': datetime.date(2017, 7, 1)
}, {
    'patient_notes': 5,
    'month': datetime.date(2017, 8, 1)
}, {
    'patient_notes': 5,
    'month': datetime.date(2017, 12, 1)
}]

第二个清单是:

[{
    'employee_notes': 4,
    'month': datetime.date(2017, 2, 1)
}, {
    'employee_notes': 4,
    'month': datetime.date(2017, 3, 1)
}, {
    'employee_notes': 4,
    'month': datetime.date(2017, 4, 1)
}, {
    'employee_notes': 4,
    'month': datetime.date(2017, 8, 1)
}, {
    'employee_notes': 4,
    'month': datetime.date(2017, 9, 1)
}, {
    'employee_notes': 4,
    'month': datetime.date(2017, 10, 1)
},  {
    'employee_notes': 4,
    'month': datetime.date(2017, 12, 1)
}]

所以我需要构建一个新列表,其中包含每月两个列表的总和,如下所示:

[{
    'total_messages': 14,
    'month': '2017-01-01'
}, {
    'total_messages': 14,
    'month': '2017-02-01'
}, {
    'total_messages': 14,
    'month': '2017-03-01'
}, {
    'total_messages': 14,
    'month': '2017-04-01'
}, {
    'total_messages': 14,
    'month': '2017-05-01'
}, {
    'total_messages': 14,
    'month': '2017-06-01'
}, {
    'total_messages': 14,
    'month': '2017-07-01'
}, {
    'total_messages': 14,
    'month': '2017-08-01'
}, {
    'total_messages': 14,
    'month': '2017-09-01'
}, {
    'total_messages': 14,
    'month': '2017-10-01'
}, {
    'total_messages': 14,
    'month': '2017-11-01'
}, {
    'total_messages': 14,
    'month': '2017-12-01'
}]

我首先尝试使用zip,但这只有在前2个列表大小相同时才有效。然后我尝试使用[itertools.izip_longest],但如果列表大小相同但月份不同,则会出现问题...我不能简单地汇总这些...我只需要汇总匹配的月份

计数器对此也很好,但我无法更改原始列表的键名...任何想法?

2 个答案:

答案 0 :(得分:3)

您可以使用defaultdict创建计数器。浏览第一个列表中的每个项目,并将patient_notes值添加到字典中。然后浏览第二个列表并添加employee_notes值。

现在,您需要将新的defaultdict编码为所需格式的列表。您可以使用列表推导。我按月对列表进行了排序。

from collections import defaultdict

dd = defaultdict(int)

for d in my_list_1:
    dd[d['month']] += d['patient_notes']
for d in my_list_2:
    dd[d['month']] += d['employee_notes']

result = [{'total_messages': dd[k], 'month': k} for k in sorted(dd.keys())]
>>> result
[{'month': datetime.date(2017, 1, 1), 'total_messages': 5},
 {'month': datetime.date(2017, 2, 1), 'total_messages': 9},
 {'month': datetime.date(2017, 3, 1), 'total_messages': 4},
 {'month': datetime.date(2017, 4, 1), 'total_messages': 4},
 {'month': datetime.date(2017, 5, 1), 'total_messages': 5},
 {'month': datetime.date(2017, 7, 1), 'total_messages': 5},
 {'month': datetime.date(2017, 8, 1), 'total_messages': 9},
 {'month': datetime.date(2017, 9, 1), 'total_messages': 4},
 {'month': datetime.date(2017, 10, 1), 'total_messages': 4},
 {'month': datetime.date(2017, 12, 1), 'total_messages': 9}]

答案 1 :(得分:2)

from collections import defaultdict
d_dict = defaultdict(int)
for k,v in [ i.values() for i in l1 + l2 ]:
    d_dict[k] += v
[ {'month':i.strftime("%Y-%m-%d"),'total_messages':j} for i, j in sorted(d_dict.items()) ]

输出:

[{'month': '2017-01-01', 'total_messages': 5},
 {'month': '2017-02-01', 'total_messages': 9},
 {'month': '2017-03-01', 'total_messages': 4},
 {'month': '2017-04-01', 'total_messages': 4},
 {'month': '2017-05-01', 'total_messages': 5},
 {'month': '2017-07-01', 'total_messages': 5},
 {'month': '2017-08-01', 'total_messages': 9},
 {'month': '2017-09-01', 'total_messages': 4},
 {'month': '2017-10-01', 'total_messages': 4},
 {'month': '2017-12-01', 'total_messages': 9}]