这是我尝试过的:
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)等。
我在这里误解了什么?为什么添加到列表中的每个新功能都会替换所有先前添加的功能?
最佳答案
你必须打破封闭:
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))]
或者使用切普纳指出的默认命名参数:
quadrant = [lambda x, y, sign = sign: (sign[0] * x, sign[1] * y)
for sign in ((1, -1), (1, 1), (-1, 1), (-1, -1))]
<小时/>
现在回答你的问题:
Why does each new function added to the list replace all the previously added functions?
没有函数被替换,您的列表包含四个不同的函数,如下所示:
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 () )
关于python - 对于 Python 3.3,如何使用一个 lambda 语句创建函数列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19166914/