def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda: num ** c) return nums[d]()print(fun(1, 5, 2, 0))print(fun(1, 5, 2, 1))print(fun(1, 5, 3, 1))print(fun(1, 10, 2, 1))16166481调用函数fun(1, 5, 2, 0)
意味着
【资料图】
nums = []for num in range(1, 5): nums.append(lambda: num ** 2)return nums[0]()所在列表nums中是多个匿名函数
应该依次是
lambda :1**2lambda :2**2lambda :3**2 #依次类推...那按照我们的想法,nums[0]应该是lambda :1**2,调用应该得到1才是
>>> demo1 = lambda :1**2>>> demo1()1>>> demo2 = lambda :2**2>>> demo2()4但结果并不是这样的,nums[0]()得到的结果是range()结束值=5-1时的4**2
甚至从答案可以看出来nums[1]()也是
依次类推,fun(1, 5, 3, 1)=>nums[1]()=>结束值5-1=4的三次方=>64
所以规律是有了,道理何在?
看下代码
def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda: num ** c) return nums[d]()这是因为 num不是 lambda 函数的内部变量,而是定义于外部作用域中的,并且 num是在调用 lambda 时访问的——而不是在定义时访问。循环结束时 num的值是 4,所以此时所有的函数都将返回 4**2,即 16
那要如何才能符合我们的预期呢?nums[0]()和nums[1]()是不一样的
你可以将值保存在 lambda 局部变量,以使其不依赖于全局 num的值
def fun(a, b, c, d): nums = [] for num in range(a, b): nums.append(lambda n=num: n ** c) # n = num return nums[d]()print(fun(1, 5, 2, 0)) print(fun(1, 5, 2, 1))print(fun(1, 5, 3, 1))print(fun(1, 10, 2, 1))# 依次输出1484以上 n=num创建了一个新的 lambda 本地变量 n,并在定义 lambda 时计算其值,使其与循环当前时点的 num值相同。这意味着 n的值在第 1 个 lambda 中为 0,在第 2 个 lambda 中为 1,在第 3 个中为 2,依此类推
以上参考
https://docs.python.org/zh-cn/3.9/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result
标签:
2022-03-18 15:03:32
2022-03-18 15:01:59
2022-03-18 15:00:36
2022-02-07 16:16:27
2022-02-07 16:16:27
2022-02-07 16:16:27
2022-02-07 16:16:27
2022-02-07 16:16:25
2022-02-07 16:16:25