Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Honza Javorek
Ha, že je v operator i itemgetter jsem zapomněl :-) Pak je to ještě
kompaktnější one-liner.

def summarize(data):
return (
{'a': val, 'b': sum(map(itemgetter('b'), group))}
for (val, group)
in groupby(data, key=itemgetter('a'))
)

Díky za opravu.

H


2013/4/16 Jan Bednařík jan.bedna...@gmail.com

 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.javo...@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 . staren...@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 luk...@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@py.cz
  http://www.py.cz/mailman/listinfo/python
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Petr Přikryl
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.bedna...@gmail.com
 Komu: Konference PyCZ python@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.javo...@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 . staren...@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 luk...@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@py.cz
  http://www.py.cz/mailman/listinfo/python
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



--

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Jirka Vejrazka
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 prik...@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.bedna...@gmail.com
  Komu: Konference PyCZ python@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.javo...@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 . staren...@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 luk...@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@py.cz
   http://www.py.cz/mailman/listinfo/python
  ___
  Python mailing list
  Python@py.cz
  http://www.py.cz/mailman/listinfo/python
 
 
 
  ___
  Python mailing list
  Python@py.cz
  http://www.py.cz/mailman/listinfo/python
 
 
 
 --
 
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python
 
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Petr Přikryl
O collection.Counter tu byla zmínka, ale řešení neodpovídá požadavku.

P.

__
 Od: Jirka Vejrazka jirka.vejra...@gmail.com
 Komu: Konference PyCZ python@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 prik...@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.bedna...@gmail.com
  Komu: Konference PyCZ python@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.javo...@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 . staren...@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 luk...@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@py.cz
   http://www.py.cz/mailman/listinfo/python
  ___
  Python mailing list
  Python@py.cz
  http://www.py.cz/mailman/listinfo/python
 
 
 
  ___
  Python mailing list
  Python@py.cz
  http://www.py.cz/mailman/listinfo/python
 
 
 
 --
 
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python
 
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



--

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Vladimir Macek
On 16.4.2013 10:04, Petr Přikryl wrote:
 O collection.Counter tu byla zmínka, ale řešení neodpovídá požadavku.

 P.

A já např. nepochopil požadavek a tak jsem zticha, což ve výsledku znamená,
že je tu méně možných řešení tohoto zapeklitého problému. :)

V.

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu azurIt
A já např. nepochopil požadavek a tak jsem zticha, což ve výsledku znamená,
že je tu méně možných řešení tohoto zapeklitého problému. :)


Skus si prebehnut riesenia ostatnych, zadanie bolo vcelku jasne.

azur
___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Jaroslav Lukesh

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@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Petr Přikryl
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 luk...@seznam.cz
 Komu: Konference PyCZ python@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@py.cz
http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-16 Tema obsahu Jan Bednařík
2013/4/16 Jaroslav Lukesh luk...@seznam.cz

 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.



Je na to spousta nástrojů, třeba ty itertools. Chce to jen méně zkoušet
metodou pokus omyl a více koukat do nápovědy :-)



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



Jde to třeba takto (upravené řešení od Honzy Javorka):

from itertools import groupby
from operator import itemgetter

def summarize(data):
return [{'a': a, 'b': sum(map(itemgetter('b'), group)), 'c': c} for (a,
c), group in groupby(data, itemgetter('a', 'c'))]


A kdybys to chtěl pomocí cyklů, tak třeba takto:

from itertools import groupby
from operator import itemgetter

def summarize(data):
groups = groupby(data, itemgetter('a', 'c'))
out = []
for (a, c), group in groups:
b = sum(map(itemgetter('b'), group))
out.append({'a': a, 'b': b, 'c': c})
return out


Honza
___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

[python] Suma podle klice slovniku v seznamu

2013-04-15 Tema obsahu Jaroslav Lukesh

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@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-15 Tema obsahu starenka .
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 luk...@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@py.cz
 http://www.py.cz/mailman/listinfo/python
___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-15 Tema obsahu azurIt
Ahoj,

nie som si isty, ci na toto najdes nejaky 'jednoduchy figel'. Proste to prejdi 
jednym cyklom a hodnoty spocitaj do druheho slovniku.

azur



__
 Od: Jaroslav Lukesh luk...@seznam.cz
 Komu: Konference PyCZ python@py.cz
 Dátum: 15.04.2013 21:59
 Predmet: [python] Suma podle klice slovniku v seznamu

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@py.cz
http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python


Re: [python] Suma podle klice slovniku v seznamu

2013-04-15 Tema obsahu Honza Javorek
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 . staren...@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 luk...@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@py.cz
  http://www.py.cz/mailman/listinfo/python
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python

Re: [python] Suma podle klice slovniku v seznamu

2013-04-15 Tema obsahu Jan Bednařík
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.javo...@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 . staren...@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 luk...@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@py.cz
  http://www.py.cz/mailman/listinfo/python
 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python



 ___
 Python mailing list
 Python@py.cz
 http://www.py.cz/mailman/listinfo/python

___
Python mailing list
Python@py.cz
http://www.py.cz/mailman/listinfo/python