Deferred_output for cyclical iteration in Python 2.x
Question: [Here](http://code.activestate.com/recipes/576961-technique-for-cyclical-
iteration/) I found a very good recipe of how to calculate a sequence of
number using a technique with **deferred output**.

I decided to use the same technique to solve the second problem from [Project
Euler](http://projecteuler.net/problems).

The code:

    
    
    #Answer: 4613732
    from itertools import *
    import operator
    
    seeds = [1,2]
    
    def deferred_output():
        for i in output:
            yield i
    
    result,a1,a2 = tee(deferred_output(),3)
    paired = map(operator.add,a1,islice(a2,1,None))
    output = chain(seeds,paired)
    
    cropped = takewhile((4000000).__gt__,result)
    evened = filter(lambda x: x%2==0,cropped)
    
    print(sum(evened))
    

The code worked perfectly in Python 3.x

But when I tried to run it in Python 2.x the following error rose:

    
    
    Traceback (most recent call last):
      File "C:\Documents and Settings\Oleg\Мои документы\_Мои документы\_SyncedWithFlashDrive\Программирование\Project Euler\2\1.py", line 14, in <module>
        paired = map(operator.add,a1,islice(a2,1,None))
      File "C:\Documents and Settings\Oleg\Мои документы\_Мои документы\_SyncedWithFlashDrive\Программирование\Project Euler\2\1.py", line 9, in deferred_output
        for i in output:
    NameError: global name 'output' is not defined
    

It means that **deferred output** doesn't work in Python 2.x

Why is that?


Answer: the following code works:

    
    
    from itertools import *                                                         
    import operator                                                                 
    
    seeds = [1,2]                                                                   
    
    def deffered_output():                                                          
        for i in output:                                                            
            yield i
    
    result,a1,a2 = tee(deffered_output(),3)
    paired = imap(operator.add,a1,islice(a2,1,None))   # change 2 (imap)
    output = chain(seeds,paired)
    
    cropped = takewhile(lambda x: x <= 4000000,result) # change 1 (lambda)
    evened = filter(lambda x: x%2==0,cropped)
    
    print(sum(evened))
    

and i needed to make two changes:

first, the argument to takewhile needs to be a lambda because integers in 2.7
don't have methods like `__gt__`.

second, and more importantly, `map()` in python 3 is lazy - it returns a
generator that does the work later. in contrast, in python 2.7, it is eager -
it does the work straight away and returns a list.

so, in python 2.7, the `map()` triggers evaluation of the code, which calls
back through the various generators until it evaluates the `deffered_output()`
function. and this all occurs _before_ the line where `output` is defined. so
there is an error, because `output` is undefined.

however, in python 3 (or when using `imap()` in python 2.7) that line creates
another generator, which doesn't actually do the work until things are
evaluated in the `sum()` (and by that point, `output` is defined, so it's ok
for `deffered_output` to be evaluated).

if that's not clear then you need to learn more about
[generators](http://wiki.python.org/moin/Generators) in python.

ps not important, but it's driving me crazy to look at it: it's "deferred",
not "deffered"!

