Pergunta

Have a python list of dict as following:

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.

Foi útil?

Solução

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}}

Outras dicas

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))

An easy way to keep a running total is to use 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])
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top