对于Python 3.3,如何使用一个lambda语句创建函数列表?

时间:2013-10-03 18:49:23

标签: python lambda python-3.3

以下是我的尝试:

quadrant = [lambda x, y: (sign[0] * x, sign[1] * y)
    for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

我期望从这一行获得的是一个函数列表,每个函数返回输入值并应用一些符号集。例如,象限[1](x,y) - > (x,y),象限[2](x,y) - > (-x,y),依此类推。

我实际得到的是一个包含四个相同函数的列表,这是我放入列表的所有最后一个函数。例如,象限[1](x,y) - > (-x,-y),象限[2](x,y) - > (-x,-y),等等。

我在这里误解了什么?为什么添加到列表中的每个新函数都会替换以前添加的所有函数?

1 个答案:

答案 0 :(得分:1)

你必须突破关闭:

quadrant = [ (lambda sign: lambda x, y: (sign[0] * x, sign[1] * y) ) (sign)
    for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

或者以Blender指出的命名函数:

def wrapper (sign):
    def makeQuadrant (x, y):
        return (sign [0] * x, sign [1] * y)
    return makeQuadrant

quadrant = [wrapper (sign) for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

或者使用chepner指出的默认命名参数:

quadrant = [lambda x, y, sign = sign: (sign[0] * x, sign[1] * y)
    for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

现在回答你的问题:

  

为什么添加到列表中的每个新函数都会替换所有   以前添加的功能?

没有替换任何功能,您的列表包含四个不同的功能,如您所见:

quadrant = [lambda x, y: (sign[0] * x, sign[1] * y, id (sign) )
    for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

for q in quadrant:
    print (id (q) )

当调用函数时,会查找sign的值。 sign的当前值是列表推导期间分配的最后一个值,(-1, -1)。这可以在这里看到:

quadrant = [lambda x, y: (sign[0] * x, sign[1] * y, id (sign) )
    for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]

for q in quadrant:
    print (q (2, 3) )

您可能希望看一下“范围”和“闭包”以便进一步阅读。

你的例子基本归结为:

fs = [lambda: x for x in range (10) ]
for f in fs: print (f () )