简体   繁体   English

字典列表的运行总计

[英]Running total for list of dict

Have a python list of dict as following:有一个 dict 的 python 列表如下:

Dict1 = [{'date': 1, 'name': 'xyz', 'qty': 100},
         {'date': 1, 'name': 'xyz', 'qty': 200},
         {'date': 1, 'name': 'xyz', 'qty': 300},
         {'date': 1, 'name': 'xyz2', 'qty': 30},
         {'date': 2, 'name': 'xyz', 'qty': 1000},
         {'date': 2, 'name': 'xyz2', 'qty': 300},
         {'date': 3, 'name': 'xyz', 'qty': 500},
         {'date': 3, 'name': 'xyz2', 'qty': 500},
         {'date': 3, 'name': 'xyz3', 'qty': 500},
         {'date': 3, 'name': 'xyz', 'qty': 600}]

Would like to to get running total of qty for each name for each date:想要为每个日期的每个名称获取运行总数:

date:1,name:xyz,qty:600
date:1,name:xyz2,qty:30
date:2,name:xyz,qty:1600
date:2,name:xyz2,qty:330
date:3,name:xyz,qty:2700
date:3,name:xyz2,qty:830
date:3,name:xyz3,qty:500

Thanks.谢谢。

from itertools import groupby
from operator import itemgetter
for k, gr in groupby(Dict1, key=itemgetter('date', 'name')):
    print "date:%i,name:%s,qty:%i" % (k[0], k[1], sum(d['qty'] for d in gr))

I assumed date is increasing order.我假设日期是递增的。

# store values
tot = {}
# the last date 
date0 = Dict1[-1]['date']

# easier to work from back, i found
for line in Dict1[-1::-1]:
    date, name, qty = [line[x] for x in 'date', 'name', 'qty']

    # add the value to all subsequent days
    for d in range(date, date0+1): 
        tot.setdefault(d, {}).setdefault(name, [0])[0] += qty

# i was putting value into array, and i put it out into a scalar
tot = dict((k, dict((kk,vv[0]) for kk,vv in v.items())) for k,v in tot.items())
print tot

Results:结果:

{1: {'xyz': 600, 'xyz2': 30}, 2: {'xyz': 1600, 'xyz2': 330}, 3: {'xyz': 2700, 'xyz3': 500, 'xyz2': 830}}

An easy way to keep a running total is to use collections.defaultdict :保持运行总数的一种简单方法是使用collections.defaultdict

from collections import defaultdict

totals = defaultdict(int)

for d in Dict1:
    name = d['name']
    # increment total
    totals[name] += d['qty']
    print 'date:%s,name:%s,qty:%d' % (d['date'], name, totals[name])

I found only some complicated way:我只发现了一些复杂的方法:

items = {}
for item in Dict1:
    key = (item['date'], item['name'])
    items.setdefault(key, 0)
    items[key] += item['qty']

Dict2 = sorted([dict(date=key[0], name=key[1], qty=qty) for key, qty in items.items()],
    key=labmda x: (x['date', x['name']))
result = {}
for date, name in [ (d['date'], d['name']) for d in Dict1]:
    result[(date, name)] = sum( [ d['qty'] for d in Dict1 if d['date'] <= date and d['name'] == name] )
keys = result.keys()
keys.sort()
for key in keys:
    print "date:%d, name:%s, qty:%d"%(key[0], key[-1], result[key])

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

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