如果该dicts中的某些关键字具有相同的月份,如何对dicts中的值求和?

时间:2016-05-06 17:33:11

标签: python django dictionary sum

我有Django查询集:

summary = Contracts.objects.all() \
                   .filter(datestart__gte=time_threshold) \
                   .values('datestart', 'id_deposits__id_valuta__name') \
                   .annotate(sum=Sum('suma')) \
                   .order_by('-id_deposits__id_valuta__name')

我抓住了qs:

for s in summary:
    for k, v in CURRENCY.items():
        if s['id_deposits__id_valuta__name'] == k:
            s['sum'] *= CURRENCY[k]

根据需要更新货币总和。它返回dicts

{'sum': Decimal('400000.00'), 'datestart': datetime.date(2016, 3, 1), 'id_deposits__id_valuta__name': 'Гривня'}
{'sum': Decimal('2500000.00'), 'datestart': datetime.date(2016, 4, 25), 'id_deposits__id_valuta__name': 'Долар'}
{'sum': Decimal('2500000.00'), 'datestart': datetime.date(2016, 4, 25), 'id_deposits__id_valuta__name': 'Долар'}

现在我需要总结" sum"的值。关键词,当几个月在" datestart"价值相等。

实施例。一些dicts有sum,datestart键。我需要总和'总和'当dicts具有相同月份时的值:2016-04-03,2016-04-14

那么如何以简约的方式做到这一点?

2 个答案:

答案 0 :(得分:2)

您可以将每个字典转换为Counter,其中月份为关键字,值为s['sum'],然后将它们添加到一起:

from collections import Counter

sum((Counter({x['datestart'].month: x['sum']}) for x in summary), Counter()) 
# Counter({4: Decimal('5000000.00'), 3: Decimal('400000.00')})

请注意,如果您需要区分月份和年份,请改为使用{(x['datestart'].month, x['datestart'].year): x['sum']}

答案 1 :(得分:1)

使用字典跟踪每月的总和;您可以在此处使用defaultdict来管理初始值:

from collections import defaultdict
from decimal import Decimal

per_month = defaultdict(Decimal)

for s in summary:
    s['sum'] *= CURRENCY.get(s['id_deposits__id_valuta__name'], 1)
    month = s['datestart'].year, s['datestart'].month
    per_month[month] += s['sum']

我已将您的循环移除CURRENCY.items();您可以使用dict.get()来获取值;如果密钥不在字典中,则使用1代替。

请注意,我正在对(year, month)元组的总和进行分组,假设您希望将不同年份的月份视为单独的总和。