[python] Suma podle klice slovniku v seznamu

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


O collection.Counter tu byla zmínka, ale řešení neodpovídá požadavku.

P.

______________________________________________________________
> Od: "Jirka Vejrazka" <jirka.vejrazka na gmail.com>
> Komu: Konference PyCZ <python na py.cz>
> Datum: 16.04.2013 09:58
> Předmět: Re: [python] Suma podle klice slovniku v seznamu
>
>Trochu mi unika, proc se tady resi onelinery, kdyz uz starenka napsal
>skvele reseni pres collections.Counter, ktery je k tomu primo urceny :)
>
>   Jirka
>
>
>2013/4/16 Petr Přikryl <prikryl na atlas.cz>
>
>> Ahoj všeci,
>>
>> Já bych přece jen zůstal u těch cyklů a pořádně to okomentoval. Jedna věc
>> je
>> nějak to napsat a druhá věc je být schopný  po roce znovu pochopit, co jsem
>> tím myslel (v lepším případě) nebo co tím myslel někdo druhý (v tom
>> horším).
>>
>> lst1 = [{'a':4,'b':3},{'a':4,'b':5},{'a':1,'b':3},{'a':3,'b':2}]
>> print('puvodni seznam slovniku:', lst1)
>>
>> lst2 = [(x['a'], x['b']) for x in lst1]
>> print('seznam dvojic hodnot:', lst2)
>>
>> d = {}
>> for a, b in lst2:
>>     d[a] = d.get(a, 0) + b  # dosavadní součet nebo nula plus nová hodnota
>> print('slovnik sum:', d)
>>
>> lst3 = [{'a': a, 'b': b} for a, b in d.items()]
>> print('vysledny seznam:', lst3)
>>
>> Když vynecháte ty tři meziprinty, není to ani moc dlouhé.
>>
>> Kdo má chuť a čas, mohl by zkusit nějaký větší příklad a timeit.
>>
>> Ona je ale otázka, jak vůbec vznikl ten původní seznam. Připadá mi to
>> jako databázová tabulka se sloupci A a B. Jestli by nebylo lepší použít
>> opravdovou tabulku (sqlite) a opravdový SQL dotaz.
>>
>> Mějte se fajn,
>>     Petr
>>
>> ______________________________________________________________
>> > Od: "Jan Bednařík" <jan.bednarik na gmail.com>
>> > Komu: Konference PyCZ <python na py.cz>
>> > Datum: 16.04.2013 00:32
>> > Předmět: Re: [python] Suma podle klice slovniku v seznamu
>> >
>> >Myslím že to využití groupby je parádní. Je to snadno čitelné, jednoduché
>> a
>> >elegantní řešení. Těžko to půjde napsat čitelnějí pomocí cyklů. Ostatně
>> >právě kvůli tomuto příkladu existuje funkce groupby.
>> >
>> >Jen bych to lehce vylepšil použitím operator.itemgetter místo těch lambda
>> >funkcí, tzn.:
>> >
>> >from operator import itemgetter
>> >
>> >get_a = itemgetter('a')
>> >get_b = itemgetter('b')
>> >
>> >
>> >
>> >2013/4/15 Honza Javorek <jan.javorek na gmail.com>
>> >
>> >> Jde to samozřejmě v podstatě one-linerem, ale bude to nečitelný.
>> >>
>> >>
>> >>
>> >> from itertools import groupby
>> >>
>> >>
>> >> def summarize(data):
>> >>     get_b = lambda x: x['b']
>> >>     get_a = lambda x: x['a']
>> >>     return (
>> >>         {'a': val, 'b': sum(map(get_b, group))}
>> >>         for (val, group)
>> >>         in groupby(data, key=get_a)
>> >>     )
>> >>
>> >> data = [{'a': 4, 'b': 3}, {'a': 4, 'b': 5}, {'a': 1, 'b': 3}, {'a': 3,
>> >> 'b': 2}]
>> >> print list(summarize(data))  # [{'a': 4, 'b': 8}, {'a': 1, 'b': 3},
>> {'a':
>> >> 3, 'b': 2}]
>> >>
>> >>
>> >>
>> >> Já bych to udělal normálně cyklama, ať se v tom jde vyznat.
>> >>
>> >> H
>> >>
>> >>
>> >>
>> >> 2013/4/15 starenka . <starenka0 na gmail.com>
>> >>
>> >> Ahoj, dal sem si malyho panaka, abych to pochopil, ale porad nechapu,
>> >>> pokud by ti nahodou slo o sumu cisel u klicu, tak collections.Counter:
>> >>>
>> >>> >>> import collections
>> >>> >>> c = collections.Counter()
>> >>> >>> for one in
>> [{'a':4,'b':3},{'a':4,'b':5},{'a':1,'b':3},{'a':3,'b':2}]:
>> >>> ...     c.update(one)
>> >>> ...
>> >>> >>> c
>> >>> Counter({'b': 13, 'a': 12})
>> >>>
>> >>> Ale asi chces neco jinyho, v tom pripade mi to asi lip vysvetli,
>> >>> protoze jsem z pomalejsich
>> >>>
>> >>> s
>> >>> ---
>> >>> In Perl you shoot yourself in the foot, but nobody can understand how
>> >>> you did it. Six months later, neither can you. | print
>> >>> 'aknerats'[::-1]
>> >>>
>> >>>
>> >>> 2013/4/15 Jaroslav Lukesh <lukesh na seznam.cz>:
>> >>> > Dobrý den,
>> >>> >
>> >>> > existuje na toto nějaký jednoduchý fígl?
>> >>> >
>> >>> > mám zdroj (první dva slovníky jsou za sebou abyste je nemuseli
>> hledat,
>> >>> jinak
>> >>> > jsou rozmístěná všeljak)
>> >>> > [{'a':4,'b':3},{'a':4,'b':5},{'a':1,'b':3},{'a':3,'b':2}]
>> >>> >
>> >>> > a chci ve výsledku sesumírovat všecky b podle stejného klíče a,
>> takto:
>> >>> >
>> >>> > [{'a':4,'b':8},{'a':1,'b':3},{'a':3,'b':2}]
>> >>> >
>> >>> > hodnota klíče a je obecná, tedy je to text, ne číslo.
>> >>> >
>> >>> > Děkuji, JL.
>> >>> > _______________________________________________
>> >>> > Python mailing list
>> >>> > Python na py.cz
>> >>> > http://www.py.cz/mailman/listinfo/python
>> >>> _______________________________________________
>> >>> Python mailing list
>> >>> Python na py.cz
>> >>> http://www.py.cz/mailman/listinfo/python
>> >>>
>> >>
>> >>
>> >> _______________________________________________
>> >> Python mailing list
>> >> Python na py.cz
>> >> http://www.py.cz/mailman/listinfo/python
>> >>
>> >
>> >
>> >----------
>> >
>> >_______________________________________________
>> >Python mailing list
>> >Python na py.cz
>> >http://www.py.cz/mailman/listinfo/python
>> >
>> _______________________________________________
>> Python mailing list
>> Python na py.cz
>> http://www.py.cz/mailman/listinfo/python
>>
>
>
>----------
>
>_______________________________________________
>Python mailing list
>Python na py.cz
>http://www.py.cz/mailman/listinfo/python
>


Další informace o konferenci Python