Python 之 for循环中的lambda
第一种
f = [lambda x: x*i for i in range(4)] (如果将x换成i,调用时候就不用传参数,结果都为3)
对于上面的表达式,调用结果:
- >>> f = [lambda x:x*i for i in range(4)]
- >>> f[0](1)
- 3 # 1*3
- >>> f[1](1)
- 3 # 1*3
- >>> f[2](1)
- 3 # 1*3
- >>> f[3](1)
- 3 # 1*3
>>> f[0](3)- 9 # 3*3
- >>> f[1](3)
- 9 # 3*3
- >>> f[2](3)
- 9 # 3*3
- >>> f[3](3)
- 9 # 3*3
上面的表达式展开如下:
- def func():
- fs = []
- for i in range(4):
- def lam(x):
- return x*i
- fs.append(lam)
- return fs
当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。因为在每次循环中 lam函数都未绑定 i 的值,所以直到循环结束,i 的值为3,并将 lam 中所用到的 i 值定为 3 ,因此真正调用(例如f[0](3))的时候 i 值保持不变(为3)。
展开后的调用方法:
- >>> def func():
- ... fs = []
- ... for i in range(4):
- ... def lam(x):
- ... return x*i
- ... fs.append(lam)
- ... return fs
- ...
- >>> f = func()
- >>> f[0](3)
- 9
- >>> f[2](3)
- 9
- >>> f[1](3)
- 9
另一种将x换成i,就与传入的x值无关了。(这里 lambda 后面什么参数都不跟)
- >>> f = [lambda :i*i for i in range(4)]
- >>> f[0]()
- 9
- >>> f[1]()
- 9
- >>> f[2]()
- 9
- >>> f[3]()
- 9
解释同上面。
第二种
f1 = [lambda i=i: i*i for i in range(4)]
对于上面的表达式,调用结果:
- >>> f1 = [lambda i=i: i*i for i in range(4)]
- >>> f1[0]()
- 0
- >>> f1[1]()
- 1
- >>> f1[2]()
- 4
- >>> f1[3]()
- 9
上面的表达式展开如下(为了更直观,替换了变量):
- def func():
- fs = []
- for i in range(4)
- def lam(x=i): # 即 i=i
- return x*x # 即 i*i
- fs.append(lam)
- return fs
当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。但是在每次循环中 lam函数都将 i 值绑定到了 x 上,所以直到循环结束,不同地址的 lam 函数的 x 值为都不一样,因此真正调用(例如 f[0]())的时候 x 值都为当时被绑定的值。
但如果给 lam 函数传了参数,例如 f[0](8),那么所有的调用结果都为传参的平方。与上面解释并不冲突,只是将传的参数绑定到了 x 上。
- >>> f1 = [lambda i=i: i*i for i in range(4)]
- >>> f1[0](8)
- 64
- >>> f1[1](8)
- 64
- >>> f1[2](8)
- 64
- >>> f1[3](8)
- 64
最后一种
f2 = [lambda x=i: i*i for i in range(4)]
哈哈哈哈,和第二种好像,只是变了一个字符,那么结果就大不一样了,哈哈哈哈
对于上面的表达式,调用结果:
- >>> f2 = [lambda x=i: i*i for i in range(4)]
- >>> f2[0]()
- 9
- >>> f2[1]()
- 9
- >>> f2[2]()
- 9
- >>> f2[3]()
- 9
- >>> f2[0](7)
- 9
- >>> f2[1](7)
- 9
- >>> f2[2](7)
- 9
传不传参数都不影响结果。展开后:
- def func():
- fs = []
- for i in range(4)
- def lam(x=i):
- return i*i
- fs.append(lam)
- return fs
虽然 lam 函数将 i 的值绑定到了 x 上,但函数体中并未使用 x,所以直到循环结束,i 的值变为3,才会在调用时使用。其实同第一种情况是一样的。
最后:我写的也好乱,还是多试试吧。
Python 之 for循环中的lambda的更多相关文章
- python:笔记for循环中的else
我们常常会在for循环遍历一个序列或者字典后,接着语句else,很多新手会误以为是判断执行else后面的 代码,其实不然,for循环里面也不存在判断,而已执行完遍历的对象后,再执行else后面的代码. ...
- Python3 循环_break和continue语句及循环中的else子句
break和continue语句及循环中的else子句break语句可以跳出for和while的循环体.如果你从for或while循环中终止,任何对应的循环else块将不执行. continue语句被 ...
- for循环中i--的妙用 及 两变量互换数值的问题
int[] array = new int[4]; for(int i = 0; i < array.length; i++){ array[i] = (int)(Math.random() * ...
- 在jquery中each循环中,要用return false代替break,return true代替continue。
在jquery中each循环中,要用return false代替break,return true代替continue. $.each(data, function (n, value) { if(v ...
- JavaScript形而上的For循环中的Break
break相当于循环中的GOTO,需避免使用. 下面是一个break使用例子. 找出第一个months小于7的项目. const cats = [ { name: 'Mojo', months: 84 ...
- vue 如何在循环中 "监听" 的绑定v-model数据
vue 如何在循环中 "监听" 的绑定v-model数据 阅读目录 vue 如何在循环中 "监听" 的绑定v-model数据 1. 普通属性的值进行监听 2. ...
- Java循环中try...finally...遇到continue
一段很简单的代码,先自己在大脑中给出结果: for (int i = 0; i < 5; i++) { System.out.println("enter: i=" + i) ...
- 浅谈循环中setTimeout执行顺序问题
浅谈循环中setTimeout执行顺序问题 (下面有见解一二) 期望:开始输出一个0,然后每隔一秒依次输出1,2,3,4. for (var i = 0; i < 5; i++) { setTi ...
- django for 循环中,获取序号
模板的for循环中,如何获取序号? 想过用enumerate,但是在模板中会报错 Could not parse the remainder xxx: 后来搜到 forloop.counter,完美解 ...
随机推荐
- Qt线程(4) 降低线程占用CPU
问题描述: 一般将计算量大的处理过程单独放置到一个单独的线程处理,因此很有可能你的处理过程需要while(1)或类似的操作. 也因此很有可能造成线程在处理时计算机CPU占用过高的情况. 解决办法: 降 ...
- python数据结构
. 数据结构¶ .1. 深入列表¶ 链表类型有很多方法,这里是链表类型的所有方法: list.append(x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x] . list ...
- MySQL集群在断网后再启动报"Unable to start missing node group"问题处理
总所周知,MySQL集群又名ndb cluster,而ndb就是network based database的简称,数据库节点之间依靠网络来通信和保证数据分块间的一致性.今天由于机房交换机损坏,导致集 ...
- 分布式事务(一)两阶段提交及JTA
原创文章,同步发自作者个人博客 http://www.jasongj.com/big_data/two_phase_commit/ 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或 ...
- C# 获取 oracle 存储过程的 返回值1
/// <summary> /// 返回对应表的模拟自增字段值 /// </summary> /// <param name="tablename"& ...
- 【Cocos2d-x 3.x】 场景切换生命周期、背景音乐播放和场景切换原理与源码分析
大部分游戏里有很多个场景,场景之间需要切换,有时候切换的时候会进行背景音乐的播放和停止,因此对这块内容进行了总结. 场景切换生命周期 场景切换用到的函数: bool Setting::init() { ...
- Spark 累加器
由于spark是分布式的计算,所以使得每个task间不存在共享的变量,而为了实现共享变量spark实现了两种类型 - 累加器与广播变量, 对于其概念与理解可以参考:共享变量(广播变量和累加器).可能需 ...
- ie浏览器 jsp中链接参数为中文的处理
在js中,使用 encodeURIComponent(encodeURIComponent("警情抽查"))来处理参数,例如: mini.get("khxmdm" ...
- Java学习
第一个java程序: 用记事本创建一个文件名为HelloWorld.java文件,我的目录为D:\My Documents\Java-workspace\Test\HelloWorld.java. 打 ...
- 【P1825】表达式整除
又自己写出来了好开心OvO 原题: 24点这个游戏好多人都玩过,就是给你4个数,添加相应的运算符,是否可以得到结果是24.小x在玩了很多遍这个游戏之后,想把这个游戏给改变一下.给你n个整数,在n个整数 ...