第一种

f = [lambda x: x*i for i in range(4)]  (如果将x换成i,调用时候就不用传参数,结果都为3)

对于上面的表达式,调用结果:

  1. >>> f = [lambda x:x*i for i in range(4)]
  2. >>> f[0](1)
  3. 3 # 1*3
  4. >>> f[1](1)
  5. 3 # 1*3
  6. >>> f[2](1)
  7. 3 # 1*3
  8. >>> f[3](1)
  9. 3 # 1*3
    >>> f[0](3)
  10. 9 # 3*3
  11. >>> f[1](3)
  12. 9 # 3*3
  13. >>> f[2](3)
  14. 9 # 3*3
  15. >>> f[3](3)
  16. 9 # 3*3

上面的表达式展开如下:

  1. def func():
  2. fs = []
  3. for i in range(4):
  4. def lam(x):
  5. return x*i
  6. fs.append(lam)
  7. return fs

当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。因为在每次循环中 lam函数都未绑定 i 的值,所以直到循环结束,i 的值为3,并将 lam 中所用到的 i 值定为 3 ,因此真正调用(例如f[0](3))的时候 i 值保持不变(为3)。

展开后的调用方法:

  1. >>> def func():
  2. ... fs = []
  3. ... for i in range(4):
  4. ... def lam(x):
  5. ... return x*i
  6. ... fs.append(lam)
  7. ... return fs
  8. ...
  9. >>> f = func()
  10. >>> f[0](3)
  11. 9
  12. >>> f[2](3)
  13. 9
  14. >>> f[1](3)
  15. 9

另一种将x换成i,就与传入的x值无关了。(这里 lambda 后面什么参数都不跟)

  1. >>> f = [lambda :i*i for i in range(4)]
  2. >>> f[0]()
  3. 9
  4. >>> f[1]()
  5. 9
  6. >>> f[2]()
  7. 9
  8. >>> f[3]()
  9. 9

解释同上面。

第二种

f1 = [lambda i=i: i*i for i in range(4)] 

对于上面的表达式,调用结果:

  1. >>> f1 = [lambda i=i: i*i for i in range(4)]
  2. >>> f1[0]()
  3. 0
  4. >>> f1[1]()
  5. 1
  6. >>> f1[2]()
  7. 4
  8. >>> f1[3]()
  9. 9

上面的表达式展开如下(为了更直观,替换了变量):

  1. def func():
  2. fs = []
  3. for i in range(4)
  4. def lam(x=i): # 即 i=i
  5. return x*x # 即 i*i
  6. fs.append(lam)
  7. return fs

当调用 func() 时,每循环一次,将 lam 函数的地址存到 fs 中。但是在每次循环中 lam函数都将 i 值绑定到了 x 上,所以直到循环结束,不同地址的 lam 函数的 x 值为都不一样,因此真正调用(例如 f[0]())的时候 x 值都为当时被绑定的值。

但如果给 lam 函数传了参数,例如 f[0](8),那么所有的调用结果都为传参的平方。与上面解释并不冲突,只是将传的参数绑定到了 x 上。

  1. >>> f1 = [lambda i=i: i*i for i in range(4)]
  2. >>> f1[0](8)
  3. 64
  4. >>> f1[1](8)
  5. 64
  6. >>> f1[2](8)
  7. 64
  8. >>> f1[3](8)
  9. 64

最后一种

f2 = [lambda x=i: i*i for i in range(4)]

哈哈哈哈,和第二种好像,只是变了一个字符,那么结果就大不一样了,哈哈哈哈

对于上面的表达式,调用结果:

  1. >>> f2 = [lambda x=i: i*i for i in range(4)]
  2. >>> f2[0]()
  3. 9
  4. >>> f2[1]()
  5. 9
  6. >>> f2[2]()
  7. 9
  8. >>> f2[3]()
  9. 9
  10. >>> f2[0](7)
  11. 9
  12. >>> f2[1](7)
  13. 9
  14. >>> f2[2](7)
  15. 9

传不传参数都不影响结果。展开后:

  1. def func():
  2. fs = []
  3. for i in range(4)
  4. def lam(x=i):
  5. return i*i
  6. fs.append(lam)
  7. return fs

虽然 lam 函数将 i 的值绑定到了 x 上,但函数体中并未使用 x,所以直到循环结束,i 的值变为3,才会在调用时使用。其实同第一种情况是一样的。

最后:我写的也好乱,还是多试试吧。

Python 之 for循环中的lambda的更多相关文章

  1. python:笔记for循环中的else

    我们常常会在for循环遍历一个序列或者字典后,接着语句else,很多新手会误以为是判断执行else后面的 代码,其实不然,for循环里面也不存在判断,而已执行完遍历的对象后,再执行else后面的代码. ...

  2. Python3 循环_break和continue语句及循环中的else子句

    break和continue语句及循环中的else子句break语句可以跳出for和while的循环体.如果你从for或while循环中终止,任何对应的循环else块将不执行. continue语句被 ...

  3. for循环中i--的妙用 及 两变量互换数值的问题

    int[] array = new int[4]; for(int i = 0; i < array.length; i++){ array[i] = (int)(Math.random() * ...

  4. 在jquery中each循环中,要用return false代替break,return true代替continue。

    在jquery中each循环中,要用return false代替break,return true代替continue. $.each(data, function (n, value) { if(v ...

  5. JavaScript形而上的For循环中的Break

    break相当于循环中的GOTO,需避免使用. 下面是一个break使用例子. 找出第一个months小于7的项目. const cats = [ { name: 'Mojo', months: 84 ...

  6. vue 如何在循环中 "监听" 的绑定v-model数据

    vue 如何在循环中 "监听" 的绑定v-model数据 阅读目录 vue 如何在循环中 "监听" 的绑定v-model数据 1. 普通属性的值进行监听 2. ...

  7. Java循环中try...finally...遇到continue

    一段很简单的代码,先自己在大脑中给出结果: for (int i = 0; i < 5; i++) { System.out.println("enter: i=" + i) ...

  8. 浅谈循环中setTimeout执行顺序问题

    浅谈循环中setTimeout执行顺序问题 (下面有见解一二) 期望:开始输出一个0,然后每隔一秒依次输出1,2,3,4. for (var i = 0; i < 5; i++) { setTi ...

  9. django for 循环中,获取序号

    模板的for循环中,如何获取序号? 想过用enumerate,但是在模板中会报错 Could not parse the remainder xxx: 后来搜到 forloop.counter,完美解 ...

随机推荐

  1. Qt线程(4) 降低线程占用CPU

    问题描述: 一般将计算量大的处理过程单独放置到一个单独的线程处理,因此很有可能你的处理过程需要while(1)或类似的操作. 也因此很有可能造成线程在处理时计算机CPU占用过高的情况. 解决办法: 降 ...

  2. python数据结构

      . 数据结构¶ .1. 深入列表¶ 链表类型有很多方法,这里是链表类型的所有方法: list.append(x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x] . list ...

  3. MySQL集群在断网后再启动报"Unable to start missing node group"问题处理

    总所周知,MySQL集群又名ndb cluster,而ndb就是network based database的简称,数据库节点之间依靠网络来通信和保证数据分块间的一致性.今天由于机房交换机损坏,导致集 ...

  4. 分布式事务(一)两阶段提交及JTA

    原创文章,同步发自作者个人博客 http://www.jasongj.com/big_data/two_phase_commit/ 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或 ...

  5. C# 获取 oracle 存储过程的 返回值1

    /// <summary> /// 返回对应表的模拟自增字段值 /// </summary> /// <param name="tablename"& ...

  6. 【Cocos2d-x 3.x】 场景切换生命周期、背景音乐播放和场景切换原理与源码分析

    大部分游戏里有很多个场景,场景之间需要切换,有时候切换的时候会进行背景音乐的播放和停止,因此对这块内容进行了总结. 场景切换生命周期 场景切换用到的函数: bool Setting::init() { ...

  7. Spark 累加器

    由于spark是分布式的计算,所以使得每个task间不存在共享的变量,而为了实现共享变量spark实现了两种类型 - 累加器与广播变量, 对于其概念与理解可以参考:共享变量(广播变量和累加器).可能需 ...

  8. ie浏览器 jsp中链接参数为中文的处理

    在js中,使用 encodeURIComponent(encodeURIComponent("警情抽查"))来处理参数,例如: mini.get("khxmdm" ...

  9. Java学习

    第一个java程序: 用记事本创建一个文件名为HelloWorld.java文件,我的目录为D:\My Documents\Java-workspace\Test\HelloWorld.java. 打 ...

  10. 【P1825】表达式整除

    又自己写出来了好开心OvO 原题: 24点这个游戏好多人都玩过,就是给你4个数,添加相应的运算符,是否可以得到结果是24.小x在玩了很多遍这个游戏之后,想把这个游戏给改变一下.给你n个整数,在n个整数 ...