2011-06-14 56 views
6

我一直在尝试使用列表理解生成Python中的lambda函数列表。但它没有工作,列表的Python lambda函数无部分

例如

fl=[lambda x: x**i for i in range(5)] 

我有检查的其他问题,它基本上基于我的基准相同的功能。

所以我也试过部分。

from functools import partial 

fl=[partial(lambda x: x**i) for i in range(5)] 

但它没有工作。任何帮助将不胜感激。欢呼声〜

+0

@Jeff梅尔卡'FL [0](2)= FL [1](2)= 16' – phihag 2011-06-14 18:42:41

+0

嗯,这是正常的一个谜。我不认为有一种方法可以让我不被更新,因为它是对循环变量的引用。为什么你要创建这个函数列表?是否有可能使用不同的方法解决您的大问题? – 2011-06-14 19:54:32

回答

6

You're tripping over Python scopes

fl=[lambda x, i=i: x**i for i in range(5)] 
+0

有趣。所以Python在这种情况下似乎表现得与JavaScript类似。 – 2011-06-14 18:43:10

+0

这与范围确定无关。这是由于解释了外部作用域的“关闭*变量*”(Python选择共享同一个变量而不是复制其值),这与许多其他语言(例如JS和C#)的工作方式确实是相同的。 – delnan 2011-06-14 18:46:08

+1

它与范围确定有关。每个lambda具有相同的范围,这意味着它们都具有相同的变量。如果变量发生变化,所有lambda表达式的结果也会变化。将该值指定为lambda的默认参数意味着它们不再需要访问(或者甚至*保持*)外部范围。 – 2011-06-14 18:48:54

6

你实际上按名称传递了i

fl=[lambda x: x**i for i in range(5)] 

每次执行lambda时,它结合相同i的功能,所以在执行该功能时(后)它使用的i当时最新的值(这将是4)。你应该把它作为一个默认参数,而不是:

fl=[lambda x, j=i: x**j for i in range(5)] 

事实上,我注意到,你在滥用partial。这里:

fl = [partial(lambda x, y: y ** x, i) for i in range(5)] 

这也适用。

+0

感谢的人,其实我=我也使它的工作〜 – 2011-06-14 18:50:28

+0

@jerry,是的,我刚刚使用'j'因为它使它更清楚发生了什么(反正我脑海里)。 – senderle 2011-06-14 18:51:42

4

另一种常见的解决方法是使用一个封闭件:

def create_f(i): 
    def f(x): 
     return x**i 
    return f 

fl = [create_f(i) for i in range(5)]