Name bindings for inner functions.

James Stroud jstroud at mbi.ucla.edu
Sat Oct 28 22:12:58 EDT 2006


Andrea Griffini wrote:
> trevor_morgan at yahoo.com wrote:
> 
>> The following code:
>>
>> def functions():
>>     l=list()
>>     for i in range(5):
>>         def inner():
>>             return i
>>         l.append(inner)
>>     return l
>>
>>
>> print [f() for f in functions()]
>>
>>
>> returns [4,4,4,4,4], rather than the hoped for [0,1,2,3,4].  I presume
>> this is something to do with the variable i getting re-bound every time
>> we go through the loop, or something, but I'm not sure how to fix this.
> 
> 
> The problem is that "i" inside the function is indeed
> the same variable for all the functions (the one you're
> using for looping).
> 
> If you want a different variable for each function
> you can use the somewhat ugly but idiomatic
> 
> def functions():
>     l=list()
>     for i in range(5):
>         def inner(i=i):
>             return i
>         l.append(inner)
>     return l
> 
> this way every function will have its own "i" variable,
> that is initialized with the value of the loop variable
> when executing the "def" statement.
> 
> Andrea

Yet another way to skin the same cat, maybe even less ugly, depending on taste.

def make_inner(i):
   def inner():
     return i
   return inner

def functions():
   return [make_inner(i) for i in range(5)]

print [f() for f in functions()]

James

-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/



More information about the Python-list mailing list