求lambda如何跟for in range搭配
各位大佬,请问怎么理解f = 这个代码呀,不知道分析的先后顺序是什么,谢谢解答 加个括号可能好理解点:f = [(lambda : x) for x in range(3) ]
展开写就是这样:
f = []
for x in range(3):
def lambdax():
return x
f.append(lambdax) hrp 发表于 2021-1-26 14:58
加个括号可能好理解点:
三个值都是2,为什么不是0,1,2呢? 123Marchapril 发表于 2021-1-26 16:09
三个值都是2,为什么不是0,1,2呢?
因为循环到最后x的值是2,所以后面调用列表中的函数,返回x就是返回2 >>> f = []
>>> for x in range(3):
def lambdax():
return x
f.append(lambdax)
这个,当x等于0的时候,开始往f列表里插入数值,这时候就要执行lambdax程序,程序返回为x,此时x=0,那插入的数值就是0,我是哪里想错了吗?不好意思,我比较笨 hrp 发表于 2021-1-26 16:18
因为循环到最后x的值是2,所以后面调用列表中的函数,返回x就是返回2
>>> f = []
>>> for x in range(3):
def lambdax():
return x
f.append(lambdax)
这个,当x等于0的时候,开始往f列表里插入数值,这时候就要执行lambdax程序,程序返回为x,此时x=0,那插入的数值就是0,我是哪里想错了吗?不好意思,我比较笨 123Marchapril 发表于 2021-1-26 16:42
这个,当x等于0的时候,开始往f列表里插入数值,这时候就要执行lambdax程序,程序返回为x,此时x=0, ...
f.append(lambdax)时候lambdax并没有被执行哈,插入的是函数lambdax的内存地址
f.append(lambdax())才是插入lambdax的返回值 本帖最后由 逃兵 于 2021-1-26 17:01 编辑
123Marchapril 发表于 2021-1-26 16:42
这个,当x等于0的时候,开始往f列表里插入数值,这时候就要执行lambdax程序,程序返回为x,此时x=0, ...
lambda函数的返回值是x
你修改了x的值就会影响lambda的值
在这里面,x的最终值是2(range(3)),所以所有的lambda函数都指向2
你在程序的末尾写个x=10的话,所有的lambda都会指向10了
f = []
for x in range(3):
def lambdax():
return x
f.append(lambdax)
x = 10
本帖最后由 kogawananari 于 2021-1-26 18:45 编辑
>>> import functools
>>> g =
>>> g()
0
>>> g()
1
>>> g()
2
>>> 说白了就是 你以为for循环的子句有作用域 然而并没有 想要f()输出0,f()输出1 是需要有作用域的 java是有这个作用域的 python没有 所以得嵌套函数来实现 hrp 发表于 2021-1-26 16:52
f.append(lambdax)时候lambdax并没有被执行哈,插入的是函数lambdax的内存地址
f.append(lambdax())才是 ...
您好,冒昧的打扰了,对于这个代码,我分析一下我的思路您看看对吗?
>>> q = []
>>> for x in range(3):
def lambdax():
return x
q.append(lambdax)
>>> q
<function lambdax at 0x0000000002DA7310>
>>> q()
2
>>> q()
2
>>> q()
2
>>> q()
首先由于q是一个列表,那我想看看列表第一项是什么,于是我输入q,然后系统提示我有未执行的函数,(我是把<function lambdax at 0x0000000002DA7310>这样的提示看做还有未执行的函数,不知道对不对),然后既然提示我有未执行的函数,于是我就加上(),然后发现“q()”“q()”“q()”的值都为2,于是我就想是不是这样的:
在执行for x in range(3)的时候:
当x = 0时,列表q=
当x = 1时,列表q=
当x = 2时,列表q=
#这里的lambdax并不是提现在列表中真正的数值,而是作为未执行函数占一个地方(是吗?)
于是我输入q(),此时q= 中的函数lambdax开始执行,由于x的最终值落在了x=2上(这里其实还不是很懂)。所以函数lambdax的返回值都是2(包括q()和q()),也就是q=,所以以上的程序运行过程就是这样吗?我还有一个疑惑就是q=怎么显示出来?
逃兵 发表于 2021-1-26 17:00
lambda函数的返回值是x
你修改了x的值就会影响lambda的值
在这里面,x的最终值是2(range(3)),所以所 ...
老哥,您好,您说的x的最终值是2,是因为是f.append(lambdax)中的lambdax没带括号的缘故,所以只取最后一个值x=2吗? kogawananari 发表于 2021-1-26 18:50
说白了就是 你以为for循环的子句有作用域 然而并没有 想要f()输出0,f()输出1 是需要有作用域的 j ...
所以a=中的“for x in range(3)”就可以视为x=3?是吗? 本帖最后由 hrp 于 2021-1-26 22:45 编辑
123Marchapril 发表于 2021-1-26 21:10
您好,冒昧的打扰了,对于这个代码,我分析一下我的思路您看看对吗?
像<function lambdax at 0x0000000002DA7310>这样的字符串是Python中用于表示函数对象的字符串。你说它是未执行的函数不正确(函数是可以反复调用的,不是一次性的),你想象中的未执行、已执行应该是:函数对象、函数返回值。
当你输入q(),相当于执行q里的第一个函数:lambdax(),因为它返回x,这时它就开始去找x的值,由于之前for循环已经循环结束,最后一次循环x的值被for赋值2,所以lambdax找到了2,返回2。
要让q显示也简单,把q中的函数都调用一遍,拿它们的返回值就行了:q= 本帖最后由 123Marchapril 于 2021-1-26 23:14 编辑
hrp 发表于 2021-1-26 22:09
像这样的字符串是Python中用于表示函数对象的字符串。你说它是未执行的函数不正确(函数是可以反复调用 ...
非常感谢您,我再问最后一次哈:
a = [ lambda : x for x in range(30)]
这里面的for x in range(3)就直接默认成x = 2就可以了吗?
什么时候for iin range(n+1)可以直接看做 i = n
什么时候考虑i = 0时怎样怎样,i = 1时怎样怎样,...i=n时怎样怎样啊
主要是我觉得fori in range():后面带一个冒号。所以我有时候会觉得i= 0 的时候进行一次走程序,i=1的时候走一次程序,而今天这个for x in range(3) ,直接取x=3弄得我不太明白了 123Marchapril 发表于 2021-1-26 21:37
所以a=中的“for x in range(3)”就可以视为x=3?是吗?
你这个问题在别的编程语言里也有
在JS(es5)里面 for循环也不拥有作用域 在for循环里面声明的变量是外层变量
代码你应该看得懂 编程语言都是互通的
function foo(){
var arr = [];
for(var i = 0;i<10;i++){
arr = function(){
console.log(i)
}
}
return arr
}
var mylist = foo();//mylist是一个存了10个函数的数组
//此时mylist数组里的每个函数打印出来都会是10
你需要函数能依次打印0到9 就要这么写
function foo(){
var arr = [];
for(var i = 0;i < 10;i++){
arr = (function(j){
return function(){
console.log(j)
}
})(i)
}
return arr
}
var mylist = foo();
//此时mylist数组里的每个函数打印出来就是对应的i的值
同理 python 你的函数数组现在是 因为无论列表生成式还是for冒号缩进 都是没有作用域的
只有function(class)有作用域
>>> q()
2
>>> q()
2
>>> q()
2
修改成我这种双层函数
>>> import functools
>>> g =
>>> g()
0
>>> g()
1
>>> g()
2
就可以了 如果不用functools.partial那就得像下面这样
>>> g = [(lambda i : (lambda :i))(i) for i in range(3)]
>>> g()
2
>>> g()
1
>>> g()
0
123Marchapril 发表于 2021-1-26 23:09
非常感谢您,我再问最后一次哈:
a = [ lambda : x for x in range(30)]
这里面的for x in range(3) ...
这里面的for x in range(3)就直接默认成x = 2就可以了吗?
不是这个意思,x在每次循环中,肯定是分别是x=0、x=1、x=2,但要问循环结束后,x的值是多少?那肯定是最后一次给x赋值x=2。
什么时候for iin range(n+1)可以直接看做 i = n
range是左闭右开的原则(包含左边的参数,不包含右边的参数),range(3)把省略的起始参数补上就是range(0, 3),它包含0、1、2三个。
什么时候考虑i = 0时怎样怎样,i = 1时怎样怎样,...i=n时怎样怎样啊
在循环进行时。循环结束后i当然只等于最后一个值。
主要是我觉得fori in range():后面带一个冒号。所以我有时候会觉得i= 0 的时候进行一次走程序,i=1的时候走一次程序,而今天这个for x in range(3) ,直接取x=3弄得我不太明白了
纠正一下,是x=2。
你的想法是对的,但是直接取x=2那是因为for循环内f.append(lambdax)时lambdax并不关心x的值是什么,只是单纯的插入lambdax这个函数对象,最后q()时已经出了for循环的范围了(也就是q()之前循环就已经结束了),这时候x当然是最后一次循环的值x=2。
这些都是很基础的for循环、range知识。 hrp 发表于 2021-1-27 10:25
不是这个意思,x在每次循环中,肯定是分别是x=0、x=1、x=2,但要问循环结束后,x的值是多少?那肯定是 ...
谢谢你哈。我会继续加强小甲鱼课程的学习 hrp 发表于 2021-1-27 10:25
不是这个意思,x在每次循环中,肯定是分别是x=0、x=1、x=2,但要问循环结束后,x的值是多少?那肯定是 ...
不好意思,我又有一个小疑问,a = ,是怎么体现"append"这个元素的?
就是我的意思是,如果x = 0,a=,x = 1,a=,x = 2,a=,那显然列表a里面只有一个元素呀,但是最后是有三个,所以a = ,是怎么体现"append"这个元素的?
页:
[1]
2