(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

Odpovedet emailem