如何快速计算字典列表中给予列总和的元素数量?

时间:2013-12-01 01:29:46

标签: python dictionary sum

呼!那个头衔是满口的。

我有一个词典列表,从中我想提取以下内容:

for code in codes:
    for type in types:
        for color in colors:
            count  = sum(1               for d in data if d.get('code') == code and d.get('type') == type and d.get('color') == color)
            amount = sum(d.get('amount') for d in data if d.get('code') == code and d.get('type') == type and d.get('color') == color)
            cost   = sum(d.get('cost')   for d in data if d.get('code') == code and d.get('type') == type and d.get('color') == color)

我知道我可以将最后两行更改为:

tally = {k: sum(d.get(k) for d in data if d.get('code') == code and d.get('type') == type and d.get('color') == color) for k in ('amount', 'cost')}

但是还要在上面的行中包含计数吗?

3 个答案:

答案 0 :(得分:3)

您可以在此处使用conditional expression

tally = {k: sum(d.get(k) if k != 'count' else 1 for d in data if d.get('code') == code and d.get('type') == type and d.get('color') == color) for k in ('count', 'amount', 'cost')}

答案 1 :(得分:2)

不是为每个(代码,类型,颜色)组合拖拽d,而是通过它一次并存储结果:

from collections import defaultdict

counts  = defaultdict(int)
amounts = defaultdict(float)
costs   = defaultdict(float)

for d in data:
    code  = d.get('code')
    type  = d.get('type')
    color = d.get('color')
    if code in codes and type in types and color in colors:
        key = (code, type, color)
        counts [key] += 1
        amounts[key] += d.get('amount')
        costs  [key] += d.get('cost')

要获得最大速度,代码,类型和颜色应该是一个集合或字典的键。

答案 2 :(得分:0)

鉴于这里有三重嵌套的for循环,我认为将索引字典列表编入索引是值得的:

from collections import defaultdict
data_entries = defaultdict(list)
for d in data:
    data_entries[(d['code'], d['type'], d['color'])].append(d)
for code in codes:
    for type in types:
        for color in colors:
            entries = data_entries[(code, type, color)]
            count = len(entries)
            amount = sum(d.get('amount', 0) for d in entries)
            cost = sum(d.get('cost', 0) for d in entries)

然后你也可以使用Ashwini Chaudhary的答案中的条件表达式,但是当你只需要总结实际匹配的条目时它应该明显更快。 tally['count'] = len(entries)应该比dict理解更快,但它确实需要更多的代码。