what is it, that I don't understand about python and lazy evaluation?

Brian Allen Vanderburg II BrianVanderburg2 at aim.com
Thu Aug 13 12:07:11 CEST 2009


Erik Bernoth wrote:
> Hi List,
>
> look at the following code:
>
> def evens():
>     # iterator returning even numbers
>     i = 0
>     while True:
>         yield i
>         i += 2
>
> # now get all the even numbers up to 15
> L = [n for n in evens() if n < 15]
>
> Isn't it strange, that this code runs (in a lazy language) for 
> eternity? I would expect python to to spit out (in no time):
> >> L
> [0, 2, 4, 6, 8, 10, 12, 14]
>
> after 14 it is not nessesary to evaluate evens() any further.
>
> I really started to ask myself if python really is lazy, but 
> everything else I wrote in lazy style still worked. Example:
> >> def test(txt, retval):
> ..    print(txt)
> ..    return retval
> ..
> >>> test(1, True) or test(2, True)
> 1
> True
> >>> test(1, True) and test(2, True)
> 1
> 2
> True
>
>
> Can anybody explain what happens with evens()?
>
> best regards
> Erik Bernoth
>
> PS: The code comes from a list post from 2006. You find it here: 
> http://mail.python.org/pipermail/python-list/2006-November/585783.html
In the list comprehension, it goes over all the items from the generator 
until the generator is done, and any item that is less than 15 becomes 
part of the list.  The "if n < 15" does not control when the generator 
terminates, only which results from it are selected to be part of the list.

You can pass the maximum desired value to make it terminate:

def evens(max):
    i = 0
    while i <= max:
       yield i
       i += 2

L = list(evens(15))
L: [0, 2, 4, 6, 8, 10, 12, 14]

L = [n for n in evens(15)]
L: [0, 2, 4, 6, 8, 10, 12, 14]


Brian Vanderburg II



More information about the Python-list mailing list