[python] Suma podle klice slovniku v seznamu

Petr Přikryl prikryl na atlas.cz
Úterý Duben 16 15:35:04 CEST 2013


Je to tím, že tam nedoplňuješ aktuální hodnotu toho c. Musí se zapamatovat
pro každé a. Může se zapamatovat třeba tak, že se do pomocného slovníku bude 
ukládat spolu se sumovanou hodnotou. Třeba takto:

lst1 = [{'a':4,'b':3,'c':9},{'a':4,'b':5,'c':9},{'a':1,'b':3,'c':7},{'a':3,'b':2,'c':6}]
print('puvodni seznam slovniku:', lst1)

lst2 = [(x['a'], x['b'], x['c']) for x in lst1]
print('seznam trojic hodnot:', lst2)

d = {}
for a, b, c in lst2:
    sum_lst = d.setdefault(a, [0, c]) # seznam, kde k prvnímu prvku se přičítá...
    sum_lst[0] += b                   # ... hodnota b
print('slovnik sum:', d)

lst3 = [{'a': a, 'b': b, 'c': c} for a, (b, c) in d.items()]
print('vysledny seznam:', lst3)

(Ono se to formátování zase zprasí, takže ty dva řádky se sum_lst jsou odsazené
pod for.)

Petr
______________________________________________________________
> Od: "Jaroslav Lukesh" <lukesh na seznam.cz>
> Komu: Konference PyCZ <python na py.cz>
> Datum: 16.04.2013 15:06
> Předmět: Re: [python] Suma podle klice slovniku v seznamu
>
>Ahoj a díky za rozšíření obzorů.
>
>Jsou to data ne zrovna jednoduše vycucaná z databáze, o nějaké dočasné 
>tabulcev sqlu  jsem uvažoval protože je nad tímto selektivně sečteným 
>výsledkem víc operací, ale připadalo mi to jako ne příliš čisté řešení. 
>Otrocky s pomocnýma proměnnýma to taky jde, ale chtěl jsem vědět, jeslti na 
>to není nějaký fígl, protože mi připadalo logické, aby pro práci nad poli a 
>slovníky bylo aspoň trochu něco jako je v sql.
>
>Ale mám s tím trošku problém, izoloval jsem problém pro tento příklad až 
>příliš moc, protože se mi nedaří jej rozšířit o 'c', tedy pro tento vstup 
>(podotýkám jen, že hodnota 'c' je stejná pro všechny 'a'):
>
>[{'a':4,'b':3,'c':9},{'a':4,'b':5,'c':9},{'a':1,'b':3,'c':7},{'a':3,'b':2,'c':6}]
>
>chtěl tento výstup:
>
>[{'a': 4, 'b': 8, 'c':9}, {'a': 1, 'b': 3, 'c':7}, {'a': 3, 'b': 2, 'c':6}]
>
>Tady je přehled co jsem zkoušel, tyhle dvě jdou, ale vrací špatné 'c'
>
>=========
>
>lst1 = 
>[{'a':4,'b':3,'c':9},{'a':4,'b':5,'c':9},{'a':1,'b':3,'c':7},{'a':3,'b':2,'c':6}]
>lst2 = [(x['a'], x['b'], x['c']) for x in lst1]
>d = {}
>for a, b,c in lst2:
>    d[a] = d.get(a, 0) + b  # dosavadní součet nebo nula plus nová hodnota
>lst3 = [{'a': a, 'b': b, 'c': c} for a, b in d.items()]
>print('vysledny seznam:', lst3)
>
>======
>
>from itertools import groupby
>def summarize(data):
>    get_b = lambda x: x['b']
>    get_a = lambda x: x['a']
>    get_c = lambda x: x['c']
>    return (
>        {'a': val, 'b': sum(map(get_b, group)),'c':val}
>        for (val, group)
>        in groupby(data, key=get_a)
>    )
>data= 
>[{'a':4,'b':3,'c':9},{'a':4,'b':5,'c':9},{'a':1,'b':3,'c':7},{'a':3,'b':2,'c':6}]
>print list(summarize(data))
>
>=======
>
>A toto už háže chybu
>
>from itertools import groupby
>from operator import itemgetter
>def summarize(data):
>    get_a = itemgetter('a')
>    get_b = itemgetter('b')
>    get_c = itemgetter('c')
>    return (
>        {'a': val, 'b': sum(map(get_b, group)),'c':valc}
>        for (val, group,valc)
>        in groupby(data, key=get_a)
>    )
>data= 
>[{'a':4,'b':3,'c':9},{'a':4,'b':5,'c':9},{'a':1,'b':3,'c':7},{'a':3,'b':2,'c':6}]
>print list(summarize(data))
>
>
>_______________________________________________
>Python mailing list
>Python na py.cz
>http://www.py.cz/mailman/listinfo/python
>


Další informace o konferenci Python