繁体   English   中英

如何汇总字典列表

[英]How to sum a list of dicts

获取字典列表并汇总列表中每一行中用于匹配键的所有值的最Python方式是什么?

我这样做了,但我怀疑理解力更像Python风格:

from collections import defaultdict
demandresult = defaultdict(int)   # new blank dict to store results 
for d in demandlist:
    for k,v in d.iteritems():
        demandresult[k] = demandresult[k] + v

Python中-字典中总和值问题一直都涉及相同的键,但就我而言,每行中的键可能是从未遇到过的新键。

我认为您的方法相当Pythonic。 理解力很好,但不应该过分夸张,它们会导致真正混乱的单线,就像下面的那种:)。

如果您坚持使用字典补偿:

demand_list = [{u'2018-04-29': 1, u'2018-04-30': 1, u'2018-05-01': 1}, 
               {u'2018-04-21': 1},
               {u'2018-04-18': 1, u'2018-04-19': 1, u'2018-04-17' : 1}]

d = {key:sum(i[key] for i in demand_list if key in i) 
     for key in set(a for l in demand_list for a in l.keys())}

print(d)
>>>{'2018-04-21': 1, '2018-04-17': 1, '2018-04-29': 1, '2018-04-30': 1, '2018-04-19': 1, '2018-04-18': 1, '2018-05-01': 1}

这是另一个使用collections.ChainMap获取组合键的单行代码:

>>> from collections import ChainMap
>>> {k: sum(d.get(k, 0) for d in demand_list) for k in ChainMap(*demand_list)}
{'2018-04-17': 1, '2018-04-21': 1, '2018-05-01': 1, '2018-04-30': 1, '2018-04-19': 1, '2018-04-29': 1, '2018-04-18': 1}

这很容易成为此处提出的最慢的方法。

我想您想返回每个字典的求和值列表。

list_of_dict = [
    {'a':1, 'b':2, 'c':3},
    {'d':4, 'e':5, 'f':6}
]

sum_of_each_row = [sum(v for v in d.values()) for d in list_of_dict] # [6,15]

如果要返回总和,只需将sum()包装为“ sum_of_each_row”。

编辑:

主要问题是您没有每个键的默认值,因此可以使用dict.setdefault()方法在有新键时设置默认值。

list_of_dict = [
    {'a':1, 'b':1},
    {'b':1, 'c':1},
    {'a':2}
]

d = {}
d = {k:d[k]+v if k in d.keys() else d.setdefault(k,v)
    for row in list_of_dict for k,v in row.items()} # {'a':3, 'b':2, 'c':1}

您的代码中唯一不清楚的是双重换循环。 将需求列表折叠成一个平坦的可迭代的demandlist可能会更清楚-然后,loopant会尽可能简单地呈现逻辑。 考虑:

demandlist = [{
    u'2018-04-29': 1,
    u'2018-04-30': 1,
    u'2018-05-01': 1
}, {
    u'2018-04-21': 1
}, {
    u'2018-04-18': 1,
    u'2018-04-19': 1,
    u'2018-04-17': 1
}]

import itertools as it
from collections import defaultdict

demandresult = defaultdict(int)

for k, v in it.chain.from_iterable(map(lambda d: d.items(), demandlist)):
    demandresult[k] = demandresult[k] + v

(这样, print(demandresult)打印defaultdict(<class 'int'>, {'2018-04-29': 1, '2018-04-30': 1, '2018-05-01': 1, '2018-04-21': 1, '2018-04-18': 1, '2018-04-19': 1, '2018-04-17': 1}) print(demandresult) defaultdict(<class 'int'>, {'2018-04-29': 1, '2018-04-30': 1, '2018-05-01': 1, '2018-04-21': 1, '2018-04-18': 1, '2018-04-19': 1, '2018-04-17': 1}) 。)

想象自己是第一次(或几个月后) demandlist ,我会发现自己在想:“好吧,我正在将demandlist折叠成一个关键的可迭代对象,我并不特别在乎如何,然后求和匹配的键。”

不幸的是,我需要在那里map以确保最终的可迭代对象具有键-值对… it.chain.from_iterable(demandlist)是仅键可迭代的对象,因此我需要在每个字典上调用items

请注意,与提出的许多答案不同,此实现(像您一样!)将对数据的扫描次数最小化为仅一次,即赢得性能(并且我尝试尽可能多地获得轻松的性能获胜)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM