如何在Python中减少/聚合每个多个键的dicts列表?

bar*_*tho 3 python dictionary

我有一个像这样的dicts列表:

sales_per_store_per_day = [
   {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15},
   {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16},
   {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17},
   {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18},
]
Run Code Online (Sandbox Code Playgroud)

如何减少此列表以获得每个商店的产品总数,忽略日期?上述输入的结果将是:

sales_per_store = [
   {'store':'a', 'product1':40, 'product2':8, 'product3':32},
   {'store':'b', 'product1':60, 'product2':10, 'product3':34}
]
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

使用a collections.defaultdict()来跟踪每个商店的信息,并collections.Counter()简化数字的总和:

from collections import defaultdict, Counter

by_store = defaultdict(Counter)

for info in sales_per_store_per_day:
    counts = Counter({k: v for k, v in info.items() if k not in ('store', 'date')})
    by_store[info['store']] += counts

sales_per_store = [dict(v, store=k) for k, v in by_store.items()]
Run Code Online (Sandbox Code Playgroud)

countsCounter()info字典中的每个产品构建的实例; 我假设除了storedate键之外的所有东西都是产品数量.它使用dict理解来生成一个删除了这两个键的副本.在by_store[info['store']]对给定存储当前的总计数查找(它默认为一个新的,空的Counter()对象).

最后一行然后产生你想要的输出; 带有'store'和每个产品计数的新词典,但您可能只想保持从存储到Counter对象的字典映射.

演示:

>>> from collections import defaultdict, Counter
>>> sales_per_store_per_day = [
...    {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15},
...    {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16},
...    {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17},
...    {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18},
... ]
>>> by_store = defaultdict(Counter)
>>> for info in sales_per_store_per_day:
...     counts = Counter({k: v for k, v in info.items() if k not in ('store', 'date')})
...     by_store[info['store']] += counts
... 
>>> [dict(v, store=k) for k, v in by_store.items()]
[{'store': 'a', 'product3': 32, 'product2': 8, 'product1': 40}, {'store': 'b', 'product3': 34, 'product2': 10, 'product1': 60}]
Run Code Online (Sandbox Code Playgroud)