Python 2.7 - 在字典中对重复项求和
我有一个字典的列表,像这样:
list1=[{'a':'apples', 'b':'snack','count':2},{'a':'apples','b':'lunch','count':3},{'a':'apples','b':'snack','count':3}]
我需要根据'a'和'b'这两个字段把列表中的重复项分组,并把它们的'count'值相加,结果应该是这样的:
list2=[{'a':'apples','b':'snack','count':5},{'a':'apples','b':'lunch','count':3}]
我在这里查找了很多资料,但还没有找到解决办法。非常感谢任何指点。
2 个回答
0
另一种解决方案,使用了分组(groupby)和列表、字典以及生成器的简写方式:
list1=[{'a':'apples', 'b':'snack','count':2},{'a':'apples','b':'lunch','count':3},{'a':'apples','b':'snack','count':3}]
from itertools import groupby
list1.sort()
group_func = lambda x: {key:val for key, val in x.iteritems() if key!='count'}
list2 = [dict(k, count = sum(item['count'] for item in items)) for k, items in groupby(list1, group_func)]
[{'a': 'apples', 'count': 3, 'b': 'lunch'}, {'a': 'apples', 'count': 5, 'b': 'snack'}]
解释:
- grouper函数接收一个项目,并使用字典简写的方式返回一个不包含'count'项的子字典。
- 然后,groupby会把所有原始列表中相同的子字典的项目聚集在一起。
- 最后,列表简写会遍历这些组,并对'count'项进行求和(现在使用生成器简写)。
缺点:
- 可读性较差。
- 为了让groupby正常工作,数据需要先排序,这可能会导致速度变慢。
优点:
- 如果list1已经排序,那么这种方法可能会更快。(因为在Python中,简写通常更快)
- 代码更简短。(甚至可以写成一行,虽然可能不太容易理解 :))
4
你可以使用一个叫做 defaultdict
的东西,配合一个二元组(2tuple)来统计数量,然后再把结果放回一个列表里...
list1=[{'a':'apples', 'b':'snack','count':2},{'a':'apples','b':'lunch','count':3},{'a':'apples','b':'snack','count':3}]
from collections import defaultdict
dd = defaultdict(int)
for d in list1:
dd[d['a'], d['b']] += d['count']
list2 = [{'a': k[0], 'b': k[1], 'count': v} for k, v in dd.iteritems()]
[{'a': 'apples', 'count': 3, 'b': 'lunch'}, {'a': 'apples', 'count': 5, 'b': 'snack'}]