博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 变量作用域问题(经典坑)
阅读量:4099 次
发布时间:2019-05-25

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

偶尔看到python的一个经典坑:

flist = [lambda :i for i in range(5)]for f in flist():	print(f())

按照一般逻辑,结果应该是 0 1 2 3 4

但运行结果是

44444

查了一下,主要是变量作用域问题和函数执行的问题。

出现这种情况的主要原因是,循环在python中不形成作用域。也就是说,i不仅仅在for循环内有效,for循环结束后i依然可以被使用,即循环结束后,i=4
比如说,如果这样写:

flist = [lambda :i for i in range(5)]del iflist[0]()

就会报错

NameError                                 Traceback (most recent call last)
in
() 1 flist = [lambda :i for i in range(5)]----> 2 del i 3 flist[0]()NameError: name 'i' is not defined

因为把i删除了之后,lambda就没办法找到返回值i了。

然后,只有函数在被调用的时候才运行函数内部的东西,也就是说,在遍历flist的时候,每调用一个f,lambda :i 被执行一次,但记住这时候i=4,所以所有f都返回4。

要想达到预期效果,可以稍微修改一下:

flist = [lambda x=i: x for i in range(5)]for f in flist:    print(f())

输出结果

01234

为什么这样就可以了呢?先看下面:

flist=[]for i in range(5):    def func():	    x = i        return x    flist.append(func)flist[0]()

输出结果是0。这段代码和上面是等价的。可以看到,i 的值此时被传递进了函数,也就是说,每一个 func 中都有 i值。等到循环结束,flist中的函数元素被调用的时候,因为 i 值在循环的时候已经成了每个func函数中的局部变量,也就是0 1 2 3 4,所以flist=0。

转载地址:http://wwksi.baihongyu.com/

你可能感兴趣的文章
16、Memento 备忘录模式
查看>>
Java基础篇(一)
查看>>
数据库
查看>>
mysql update与group by
查看>>
nginx反代 499 502 bad gateway 和timeout
查看>>
linux虚拟机安装tar.gz版jdk步骤详解
查看>>
python猜拳游戏
查看>>
python实现100以内自然数之和,偶数之和
查看>>
python数字逆序输出及多个print输出在同一行
查看>>
python九九乘法表(详解)
查看>>
ESP8266 WIFI数传 Pixhaw折腾笔记
查看>>
苏宁产品经理面经
查看>>
百度产品经理群面
查看>>
去哪儿一面+平安科技二面+hr面+贝贝一面+二面产品面经
查看>>
element ui 弹窗在IE11中关闭时闪现问题修复
查看>>
vue 遍历对象并动态绑定在下拉列表中
查看>>
Vue动态生成el-checkbox点击无法选中的解决方法
查看>>
python __future__
查看>>
MySQL Tricks1
查看>>
python 变量作用域问题(经典坑)
查看>>