(odpověď je dole) On 11.2.2010, at 2:35, matesfila wrote: > > Zdravím, > > mám taký trochu algoritmický problém! > > Na adrese http://code.activestate.com/recipes/576961/ som sa dopátral k pre > mňa dosť záhadnej algoritmickej konštrukcii, ktorú tam autor nazýva zhruba > ako deferred output. > > Ide o tento algoritmus: > > def fibonacci(): > """ Funkcia na počítanie Fibonachiho čísiel """ > def deferred_output(): > for i in output: > yield i > > result, c1, c2 = tee(deferred_output(), 3) > paired = map(add, c1, islice(c2, 1, None)) > output = chain([0, 1], paired) > return result > > #príklad použitia funkcie: > print(list(islice(fibonacci(), 50))) > > Sú mi jasné metódy ako list, islice, chain a myslím, že aj map, tee a > využitie generátora. > > Ale ako je možné, že v generátore sa využíva premenná, ktoré ešte nebola > nikde definovaná? !!! Pravdepodobne sa tam nejako využíva vlastnosť > generátora, ktorý premennnú 'output' využije vlastne až keď sa vyvolá next() > na generátore a v tej dobe vlastne premenná už asi existuje... ale neviem, > jaksik tie myšlienky tam využité neviem definovať a uchopiť :-) >
Ano, výraz deferred_output() nespustí kód uvnitř funkce deferred_output; protože je to generátor (to se pozná už při parsování kódu), vrátí se iterátor a teprve při procházení iterátoru se spustí kód uvnitř deferred_output. A v tom okamžiku už "volná proměnná" output existuje. Takovéto techniky bych rozhodně neoznačil za běžně používané v Pythonu. Zrovna tento kód mi nefungoval, ale asi tuším, co to dělá - deferred_output() představuje nějaký iterátor; vytvoří se "nad ním" tři nezávislé iterátory, jeden z nich se vrátí, další dva slouží ke sčítání (posledního a předposledního prvku), které je vyjádřeno iterátorem paired, a ten se (spolu s počátečními prvky - 0 a 1) vloží do deferred_output. Takže co se děje, když máš iterátor fibonacci() a zavoláš na něj next(): to, co máš, je vlastně iterátor z tee, to tee uchovává potřebnou historii (předposlední a poslední prvek, diky tomu, že další dva iterátory vzniklé z tee() právě na tyto prvky ukazují). Když chceš další prvek z result, vezme se další prvek z iterátoru vzniklého z map(), který je zadán jako součet hodnoty toho druhého a třetího iterátoru z tee(). Tedy součet předposledního a posledního čísla. Tento součet se zároveň uloží (funkcionalita tee). Asi jsem to popsal trochu zmateně, je prostě nutné se do toho kódu delší chvíli dívat :) PM _______________________________________________ Python mailing list [email protected] http://www.py.cz/mailman/listinfo/python
