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 -- http://mail.python.org/mailman/listinfo/python-list