yet another generator implementation (was Re: how to write function that returns function)

David Eppstein eppstein at ics.uci.edu
Wed May 15 14:44:44 EDT 2002


In article <wusn4t46fx.fsf_-_ at hades.layton-graphics.com>,
 George Demmy <gdemmy at layton-graphics.com> wrote:

> CL:
> 
> (defun foo (n) #'(lambda () (incf n)))
> 
> Python:
> 
> def foo(n=0):
>   class bar:
>     def __init__(self):
>       self.n = n
>     def next(self):
>       self.n += 1
>       return self.n
>   return bar().next
> 
> f = foo()
> print f(),f(),f()
> -> 2 3 4
> g = foo(1)
> -> 3 4 5

You seem to have an off by one error on your output:
I get 1 2 3 and 2 3 4

Anyway, as long as you're going to do that, why not:

from __future__ import generators

def foo(n=0):
    def bar(n=n):
        while 1:
            n += 1
            yield n
    return bar().next


[ from earlier message by same author: ]
> I don't think that the "Guido implementation" of Python allows the
> capture of state in closures the same way that you can in Scheme and
> CL, though you can fake it very easily, as above. 

I think the key difference is that Python's closures only give you read 
access to the variables.  If you want write access you have to 
encapsulate them in something else, like a list:

def foo(n=0):
    n=[n]
    def bar():
        n[0] += 1
        return n[0]
    return bar

-- 
David Eppstein       UC Irvine Dept. of Information & Computer Science
eppstein at ics.uci.edu http://www.ics.uci.edu/~eppstein/



More information about the Python-list mailing list