On Sep 28, 2:52 am, Steven D'Aprano <[EMAIL PROTECTED]
cybersource.com.au> wrote:
> On Sat, 27 Sep 2008 21:43:15 -0700, Aaron \"Castironpi\" Brady wrote:
> > Hello all,
>
> > To me, this is a somewhat unintuitive behavior.  I want to discuss the
> > parts of it I don't understand.
>
> >>>> f= [ None ]* 10
> >>>> for n in range( 10 ):
> > ...     f[ n ]= lambda: n
> > ...
> >>>> f[0]()
> > 9
> >>>> f[1]()
> > 9
>
> > I guess I can accept this part so far, though it took a little getting
> > used to.  I'm writing some code and found the following workaround, but
> > I don't think it should give different results.  Maybe I'm not
> > understanding some of the details of closures.
>
> >>>> f= [ None ]* 10
> >>>> for n in range( 10 ):
> > ...     f[ n ]= (lambda n: ( lambda: n ) )( n )
> > ...
> >>>> f[0]()
> > 0
> >>>> f[1]()
> > 1
>
> > Which is of course the desired effect.  Why doesn't the second one just
> > look up what 'n' is when I call f[0], and return 9?
>
> That's an awfully complicated solution. A much easier way to get the
> result you are after is to give each function its own local copy of n:
>
> f[n] = lambda n=n: n
>
> As for why the complicated version works, it may be clearer if you expand
> it from a one-liner:
>
> # expand: f[ n ]= (lambda n: ( lambda: n ) )( n )
>
> inner = lambda: n
> outer = lambda n: inner
> f[n] = outer(n)
>
> outer(0) => inner with a local scope of n=0
> outer(1) => inner with a local scope of n=1 etc.
>
> Then, later, when you call inner() it grabs the local scope and returns
> the number you expected.
>
> --
> Steven

Steven,

I must have misunderstood.  Here's my run of your code:

>>> inner = lambda: n
>>> outer = lambda n: inner
>>> outer(0)
<function <lambda> at 0x00A01170>
>>> a=outer(0)
>>> b=outer(1)
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
NameError: global name 'n' is not defined

Why doesn't 'inner' know it's been used in two different scopes, and
look up 'n' based on the one it's in?
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to