Quiero tener una suma de valores en un dict.
A continuación se muestra el código que he escrito.

results = collections.defaultdict(dict)
for main, month, tot in list_data:
    d = results[main]
    d[month] = tot  
    d.setdefault('total', 0)
    d['total'] += tot
result_output = dict(results)

El código anterior da la salida a continuación:

{u'Apple': {'January': 17, 'February': 1, 'total': 19, 'March': 1}, 
 u'Oranges': {'total': 1, 'March': 1}, 
 u'Graphes': {'January': 24, 'February': 1, 'total': 66, 'March': 41}}

Pero quiero una salida como esta:

{u'Apple': {'January': 17, 'February': 1, 'total': 19, 'March': 1}, 
 u'Oranges': {'total': 1, 'March': 1}, 
 u'Graphes': {'January': 24, 'February': 1, 'total': 66, 'March': 41, 'April': 1}, 
 u'grandtotal': {'January': 41 , 'February': 3, 'March': 43, 'April':1 }}

Me preguntaba si alguien podría ayudarme con este problema que estoy teniendo. Yo realmente lo apreciaría.

2
newbe 22 may. 2011 a las 01:05

4 respuestas

La mejor respuesta

¿Qué tal esto? (No probado)

from collections import defaultdict
from functools import partial

results = defaultdict(partial(defaultdict, int))
for main, month, tot in list_data:
    results[main][month] += tot
    results[main]["total"] += tot
    results[u"grandtotal"][month] += tot
result_output = dict((k, dict(v)) for k, v in results.items())

EDITAR : result_output ahora tiene valores dict en lugar de valores por defecto.

1
Lauritz V. Thaulow 21 may. 2011 a las 21:38

Puedes probar eso, no probado ...

gt = collections.defaultdict(int)         # get a new dict
results = collections.defaultdict(dict) 
for main, month, tot in list_data: 
   d = results[main]
   d[month] = tot  
   gt[month]+=tot                         # populate it
   d.setdefault('total', 0)
   d['total'] += tot
 result_output = dict(results)
 results_output['grand_total'] = gt       # save it
1
dugres 21 may. 2011 a las 21:44

Por lo tanto, desea agregar un gran total.

Si comienzas con una estructura como:

starting_data = {u'Apple': {'January': 17, 'February': 1, 'total': 19, 'March': 1}, 
                 u'Oranges': {'total': 1, 'March': 1}, 
                 u'Graphes': {'January': 24, 'February': 1, 'total': 66, 'March': 41}}

Puedes hacer algo como

grand_total = defaultdict(int) # makes it default to 0
for fruit, fruitdict in starting_data.items():
    for month, total in fruitdict.items():
        grand_total[month] += total
starting_data[u'grand_total'] = dict(grand_total)

Esto ha sido probado y da

{u'Apple': {'February': 1, 'January': 17, 'March': 1, 'total': 19},
 u'Graphes': {'February': 1, 'January': 24, 'March': 41, 'total': 66},
 u'Oranges': {'March': 1, 'total': 1},
 u'grand_total': {'February': 2, 'January': 41, 'March': 43, 'total': 86}}

Obviamente, no necesita revisar la lista nuevamente y podría agregarse antes; pero me gusta probar y no sé el formato de los datos de entrada.

0
dr jimbob 21 may. 2011 a las 21:43

Usando colecciones.

import collections

results = collections.Counter()

a = {u'Apple': {'January': 17, 'February': 1, 'total': 19, 'March': 1},
     u'Oranges': {'total': 1, 'March': 1},
     u'Graphes': {'January': 24, 'February': 1, 'total': 66, 'March': 41}}

for counts in a.values():
     results.update(counts)

print results # Counter({'total': 86, 'March': 43, 'January': 41, 'February': 2})
0
riza 22 may. 2011 a las 02:48