Scope Variable with a Loop
我读了Python官方手册中的一句话。
If a lambda or def defined within a function is nested inside a loop, and the >nested function references an enclosing scope variable that is changed by that >loop, all functions generated within the loop will have the same value—the value >the referenced variable had in the last loop iteration. In such cases, you must >still use defaults to save the variable’s current value instead.
至于剧本:
1 2 3 4 5 6 7 | def makeActions(): acts=[] for i in range(5): acts.append(lambda x: i**x) return acts acts=makeActions() print(acts) |
我知道这个问题的样子和解决方法。但我就是不明白原因。请看一下我的解释:
1 2 3 4 5 6 7 8 9 10 | def makeActions(): acts=[] for i in range(5): acts.append(lambda x: i**x) #step2-step6: each lambda would be stored #in the list, however, with its own"i" return acts acts=makeActions() #step1: when the function is called, the list would be #created. And lambda would be called as well. print(acts) |
我的观点是,在每次迭代中,即使没有给出参数x,也会调用每个lambda。因此,在列表"acts"中,每个元素(即每个lambda)具有不同的"i"。
我知道我错了,但你能告诉我为什么吗?谢谢!
为了更清楚地说明这个主题,在lambda中对
1 2 3 4 5 6 7 8 9 | def makeActions(): acts=[] for i in range(5): print('i:', i, 'object id:', id(i)) acts.append(lambda: id(i)) print('final i:', i, 'object id:', id(i)) return acts acts=makeActions() print([fn() for fn in acts]) |
退换商品
1 2 3 4 5 6 7 | i: 0 object id: 140418781832928 i: 1 object id: 140418781832960 i: 2 object id: 140418781832992 i: 3 object id: 140418781833024 i: 4 object id: 140418781833056 final i: 4 object id: 140418781833056 [140418781833056, 140418781833056, 140418781833056, 140418781833056, 140418781833056] |
来自
如果要在创建lambda时保留该值,则需要将引用的值"trap"到所需的位置和时间,例如,可以将lambda创建委托给函数:
1 2 3 4 5 6 7 8 9 10 11 12 | def delegated(d): return lambda: id(d) def makeDelegatedActions(): acts=[] for i in range(5): print('i:', i, 'object id:', id(i)) acts.append(delegated(i)) print('final i:', i, 'object id:', id(i)) return acts acts=makeDelegatedActions() print([fn() for fn in acts]) |
哪些回报
1 2 3 4 5 6 7 | i: 0 object id: 140418781832928 i: 1 object id: 140418781832960 i: 2 object id: 140418781832992 i: 3 object id: 140418781833024 i: 4 object id: 140418781833056 final i: 4 object id: 140418781833056 [140418781832928, 140418781832960, 140418781832992, 140418781833024, 140418781833056] |
这里是在线演示
每个lambda只知道从其封闭范围(即
可以工作的变体:
1 2 3 4 5 6 | def expgen(n): def myexp(x): return n**x return myexp acts = [expgen(i) for i in range(5)] |
在这种情况下,从中提取