Autogenerate functions (array of lambdas)

David Stanek dstanek at dstanek.com
Thu Sep 6 05:00:12 EDT 2007


On 9/6/07, Chris Johnson <effigies at gmail.com> wrote:
>
> What I want to do is build an array of lambda functions, like so:
>
> a = [lambda: i for i in range(10)]
>
> (This is just a demonstrative dummy array. I don't need better ways to
> achieve the above functionality.)
>
> print [f() for f in a]
>
> results in: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
> rather than the hoped for: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>
> Clearly, lambda is returning the object i, which is left at the last
> value of range(10). The following is my solution.
>
> t = lambda i: lambda: i
> a = [t(i) for i in range(10)]
>
> or the somewhat more terse:
>
> a = [(lambda i: lambda: i)(i) for i in range(10)]
>
> This gives the behavior which, intuitively, I expected from the
> original syntax. So my questions are:
> 1) Does this make sense as what should be done here? That is, would
> this be the behavior you'd want more often than not? As I said,
> intuitively, I would think the lambda would treat the iterator
> variable as a constant in this context.
> 2) Is there a better or preferred method than the one I've found?


A more explicit example of your solution would be:
    >>> def gen(i):
    ...     return lambda: i # bind to the i passed in
    ...
    >>> l = [gen(i) for i in range(10)]
    >>> [f() for f in l]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Your initial lambda: i creates a function that binds to i in the current
scope. When you wrapped that in another lambda you were creating a new scope
with a new value of i and returning a function bound to that value for i.

Take a look at closures:
  http://www.ibm.com/developerworks/linux/library/l-prog2.html#h1
  http://ivan.truemesh.com/archives/000392.html


David
--
http://www.traceback.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20070906/a7b116ce/attachment.html>


More information about the Python-list mailing list