[python] generatorovy vyraz (bylo Re: nevznik objektu)

David Rohleder davro na ics.muni.cz
Středa Březen 24 15:46:38 CET 2010


Přikryl Petr píše v St 24. 03. 2010 v 13:33 +0000:
> 
> >Od: David Rohleder
> >[...] si snažím o
> >objasnit některé věci. Imho jsou
> >napřiklad některé z těch syntaktických 
> >cukrů špatně - např. odstranění
> >závorek z generátorů (i*i for i in range(4)).
> >Ne, že by se na to nedalo
> >zvyknout, akorát to tady trochu přehnali.
> 
> Ty závorky nejsou odstraněné. Ty závorky
> nebyly nikdy potřeba... až na některé výjimky,
> jako 
> 
>   g = (i*i for i in range(4))
> 
> Jde jen o specialitu, aby překladač poznal,
> že to je generátorový výraz. Je to jako numerický
> výraz -- taky se může zapsat do závorek.

Mně vadí nekonzistence:

jde napsat 
a = fce(generátor)
nebo
a = fce((generátor))

je možné napsat
a = (generátor)

ale ne 
a = generátor

výmluvy na to, že by překladač nepoznal, že se jedná o generátor a ne o
přiřazení i*i jsou liché, protože on to musí poznat např. u té funkce.

pokud by byl tak hloupý, jak říkáš, tak by 

a = fce(i*i for i in range(4))
nahlásila taky syntax error jako v příkladu níže.

podle mne tady tyto problémy způsobuje třeba i použití kulatých závorek,
protože se pak jednoduše splete s nějakým tuple, případně dalšími
operátory. Překladač musí zjišťovat jestli se ve výrazu někde vepředu
nevyskytuje for, aby celý výraz mohl prohlásit za generátor.

Kdybych chtěl nějakou jednoznačnou syntaxi, tak bych mnohem radši použil
složené závorky:

a = { i*i | for i in range(4)}

(a samozřejmě vynechávání závorek u fce() by taky muselo přestat)

> 
> >>> g = i*i for i in range(4)
>   File "<stdin>", line 1
>     g = i*i for i in range(4)
>               ^
> SyntaxError: invalid syntax
> >>> g = (i*i for i in range(4))
> >>> g
> <generator object <genexpr> at 0x0282A580>
> 
> A určitě to není generátor n-tice. Tu si 
> ale můžu jednoduše z generátorového výrazu
> vytvořit. V níže uvedeném příkladu už ta syntaktická
> specialita není nutná, takže je to tuple() s holým
> generátorovým výrazem uvnitř:
> 
> >>> t = tuple(i*i for i in range(4))
> >>> t
> (0, 1, 4, 9)
> 
> Jde taky o to, že generátorový výraz lze napsat
> na víc řádků. Tady je jiný výraz a je to pitomost,
> ale pro ilustraci:
> 
> >>> g = (i*i
> ...        for i in range(4)
> ...        if i > 2)

to už je hodně přitažené za vlasy, normálně se jeden příkaz píše na
jeden řádek, lambda funkci taky nemůžeš napsat takovým způsobem na dva
řádky.

Tady prostě normálně funguje \ a dostaneš stejnou věc.

> >>> g
> <generator object <genexpr> at 0x0282A648>
> >>> tuple(g)
> (9,)
> 
> Kdyby tam nebyly (u toho výrazu) ty závorky,
> vypadal by for jako špatně odsazený... a vůbec 
> by to překladači mohlo hodně zamotat hlavu.
> Nehledě na to, že by se to for mohlo odsadit 
> stejně jako g a pak už by to bylo úplně divné.
> 
> pepr
> _______________________________________________
> Python mailing list
> Python na py.cz
> http://www.py.cz/mailman/listinfo/python




Další informace o konferenci Python