博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python当中的坑【闭包与lambda】
阅读量:4683 次
发布时间:2019-06-09

本文共 1335 字,大约阅读时间需要 4 分钟。

先来看一个栗子:

def create():    return [lambda x:i*x for i in range(5)]for i in create():    print(i(2))

结果:

88888

create函数的返回值时一个列表,列表的每一个元素都是一个函数 -- 将输入参数x乘以一个倍数i的函数。预期的结果时0,2,4,6,8. 但结果是5个8,意外不意外。

由于出现这个陷阱的时候经常使用了lambda,所以可能会认为是lambda的问题,但lambda表示不愿意背这个锅。问题的本质在与python中的属性查找规则,LEGB(local,enclousing,global,bulitin),在上面的例子中,i就是在闭包作用域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询得到的

 解决办法也很简单,那就是变闭包作用域为局部作用域。

def create():    return [lambda x, i=i:i*x for i in range(5)]for i in create():    print(i(2))

换种写法:

def create():    a = []    for i in range(5):        def demo(x, i=i):            return x*i        a.append(demo)    return afor i in create():    print(i(2))

以上两种写法是一样的

结果:

02468

  ---_<_>_---

再来一个问题相似的栗子

代码很简单:(声明:python3问题)

nums = range(2,20)for i in nums:    nums = filter(lambda x: x==i or x%i, nums)print(list(nums))

结果:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

同样按照正常的逻辑结果应该为:

[2, 3, 5, 7, 11, 13, 17, 19]

问题产生的原因:

  • 在python3当中filter()函数返回的是一个迭代器,因此并没有做真正的执行,而是在每次调用的时候执行(python2中filter()返回的值列表,无此现象)
  • 在遍历后执行打印时,现在执行循环当中的函数,同上面一个栗子的问题,i这个变量使用的是最后调用时的值,与以上栗子不同的是以上栗子用的是内嵌作用域的值,而这个栗子用的是全局i的值

修改代码:

nums = range(2,20)for i in nums:    nums = filter(lambda x,i=i: x==i or x%i, nums)print(list(nums))

结果:

[2, 3, 5, 7, 11, 13, 17, 19]

  

  

  

  

       

转载于:https://www.cnblogs.com/kayb/p/7468801.html

你可能感兴趣的文章
批处理文件中的路径问题
查看>>
appium+python 环境搭建
查看>>
WampServer下修改和重置MySQL密码
查看>>
hibernate出现No row with the given identifier exists问题
查看>>
为什么wait()和notify()属于Object类
查看>>
Part2_lesson3---ARM寄存器详解
查看>>
深入理解vsto,开发word插件的利器
查看>>
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同!
查看>>
导入properties时的坑
查看>>
python——网络编程
查看>>
Spark的39个机器学习库
查看>>
Electron学习笔记(一)
查看>>
Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
查看>>
配置NRPE的通讯
查看>>
VS2005编译VTK5.10.1
查看>>
shp系列(一)——利用C++进行shp文件的读(打开)与写(创建)开言
查看>>
总结上海永辉云商高级前端职位面试题集
查看>>
中国计算机学会推荐国际学术会议和期刊目录
查看>>
文本元素
查看>>
各种可以远程
查看>>