Python列表分组和总和

时间:2015-03-29 11:35:15

标签: python list dictionary

假设我有以下列表:

[{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]

我如何对其进行分组并对计数求和以获得以下结果:

[{'name': 'Amy', 'count': 3}, {'name': 'Peter', 'count': 1}]

感谢。

5 个答案:

答案 0 :(得分:5)

您可以使用collecions.Counter

from collections import Counter
l = [
    {'name': 'Amy', 'count': 1},
    {'name': 'Amy', 'count': 2}, 
    {'name': 'Peter', 'count': 1}
]
c = Counter()
for v in l:
    c[v['name']] += v['count']

结果:

>>> c
Counter({'Amy': 3, 'Peter': 1})
>>> [{'name': name, 'count': count} for name, count in c.items()]
[{'count': 3, 'name': 'Amy'}, {'count': 1, 'name': 'Peter'}]

答案 1 :(得分:3)

您也可以使用Pandas groupby功能:

df = pd.DataFrame([{'name': 'Amy', 'count': 1},
                   {'name': 'Amy', 'count': 2},
                   {'name': 'Peter', 'count': 1}])

df.groupby("name").sum()

       count
name        
Amy        3
Peter      1

答案 2 :(得分:1)

您可以使用defaultdict in the doc解释列表:

>>> l = [{'name': 'Amy', 'count': 1},
         {'name': 'Amy', 'count': 2},
         {'name': 'Peter', 'count': 1}]

# Pivot operation
>>> pivot = collections.defaultdict(list)
>>> for item in l:
...     pivot[item['name']].append(item['count'])
... 
>>> pivot
defaultdict(<class 'list'>, {'Peter': [1], 'Amy': [1, 2]})

之后,您只需使用理解列表重建我们想要的输出:

>>> [{'name':k, 'count':sum(values)} for k, values in pivot.items()]
[{'name': 'Peter', 'count': 1}, {'name': 'Amy', 'count': 3}]

我必须承认这不是最有效的方法,但考虑到你的数据结构,我想枢轴操作在其他几个场景中会很有用,不一定意味着总结。

答案 3 :(得分:1)

import itertools as it
import operator as op

l = [{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]

获取按dict的'name'键排序的列表。

sl = sorted(l,key=op.itemgetter('name'))  

将排序列表传递给gorupby,其中键作为dict的'name'键,返回键的元组和按dict的'name'键分组的列表项的迭代器。 F.E. ('Amy',<itertools._grouper object at 0xb5fdac2c>)

迭代器每次迭代产生一个项目列表的所有元素,其中'Amy'作为dict的'name'键的值。

要获取“计数”键的总和,我们必须使用sum等所有“计数”字段的新列表来调用sum(map(op.itemgetter('count'),g))

构建一个dict调用列表dict,其中groupby返回的元组最合适的元素作为'name'键的值,sum返回的总和作为'的值'计算新词典的关键。

[ dict(name=k,count=sum(map(op.itemgetter('count'),g))) 
    for k,g in it.groupby(sl, key=op.itemgetter('name'))]

答案 4 :(得分:1)

我想建议你可以使用defaultdictanswer中的Sylvain Leroux。

但是,没有必要将计数收集到列表中,您可以在使用defaultdict(int)时将它们相加:

from collections import defaultdict

l = [{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]

counts = defaultdict(int)
for d in l:
    counts[d['name']] += d['count']

counts = [{'name': k, 'count': v} for k,v in counts.items()]

>>> print counts
[{'count': 3, 'name': 'Amy'}, {'count': 1, 'name': 'Peter'}]

这应该比构建列表和总结它们更有效。

itertools.groupby是另一种选择,但它确实需要按name键排序的前期列表,这可能在较长的列表上效率较低。