在Python中聚合简单字典的最佳方法

时间:2016-05-20 22:39:54

标签: python dictionary count aggregate

我的问题很简单:我有一个dicts列表,我想在一个特定的键上对它进行计数聚合成一个新的字典。就像this一样,但是在Python中。

原始数据

mylist = [
    {'date': '16-01-2016', 'name': 'A'},
    {'date': '16-01-2016', 'name': 'B'},
    {'date': '17-01-2016', 'name': 'C'},
    {'date': '17-01-2016', 'name': 'D'},
    {'date': '17-01-2016', 'name': 'E'},
    {'date': '18-01-2016', 'name': 'F'},
]

结果

{'17-01-2016': 3, '16-01-2016': 2, '18-01-2016': 1}

如何?

实现这一目标的最佳解决方案是什么?我想做一个比丑陋的代码更漂亮和更pythonic的方式:

result = {}
for item in mylist:
    if not item['date'] in result:
        result[item['date']] = 1
    else:
        result[item['date']] += 1

非常感谢您考虑我的要求!

2 个答案:

答案 0 :(得分:3)

您可以将collections.Counter字典用于地图operator.itemgetter

from collections import Counter
from operator import itemgetter

mylist = [
    {'date': '16-01-2016', 'name': 'A'},
    {'date': '16-01-2016', 'name': 'B'},
    {'date': '17-01-2016', 'name': 'C'},
    {'date': '17-01-2016', 'name': 'D'},
    {'date': '17-01-2016', 'name': 'E'},
    {'date': '18-01-2016', 'name': 'F'},
]

counts = Counter(map(itemgetter("date"), mylist))

输出:

Counter({'17-01-2016': 3, '16-01-2016': 2, '18-01-2016': 1})

或仅使用gen exp:

counts = Counter(d["date"] for d in mylist)

如果您使用 python2 ,请使用itertools.imap代替地图。

在旁注中,if item['date'] not in result的读数优于if not item['date'] in result

如果速度非常重要,那么地图和项目符号会更快一些:

In [16]: timeit  Counter(map(itemgetter("date"), mylist))
10 loops, best of 3: 23.9 ms per loop

In [17]: timeit  Counter(d["date"] for d in mylist)
10 loops, best of 3: 26.8 ms per loop

In [18]: timeit Counter(map(lambda x: x['date'], mylist))
10 loops, best of 3: 34.9 ms per loop

答案 1 :(得分:2)

使用Counter

from collections import Counter 

Counter(map(lambda x: x['date'], mylist))
# Counter({'17-01-2016': 3, '16-01-2016': 2, '18-01-2016': 1})

Counterdict子类,因此您不必担心为打印结果添加前缀Counter