关于 [lambda x: x*i for i in range(4)] 理解
题目:
lst = [lambda x: x*i for i in range(4)]
res = [m(2) for m in lst]
print res
实际输出:[6, 6, 6, 6]
想要输出 [0, 2, 4, 6] 应该怎么改?如下:
lst = [lambda x, i=i: x*i for i in range(4)]
res = [m(2) for m in lst]
print res
这个问题涉及到了Python的闭包及延时绑定的知识(Python作用域)。
在Python核心编程里,闭包的定义如下:
如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认定是闭包。
总结为三点:
1、是一个内嵌函数
2、对外部函数变量引用
3、外部函数返回内嵌函数
简单的闭包例子:
def counter(start_at=0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
上面的那道题,可以写成这样:
def func():
fun_list = []
for i in range(4):
def foo(x):
return x*i
fun_list.append(foo)
return fun_list
for m in func():
print m(2)
func()是一个包含四个函数的列表:
[<function func at 0x00000000021CE9E8>, <function func at 0x00000000021CEA58>, <function func at 0x00000000021CEAC8>, <function func at 0x00000000021CEB38>]
当我们执行 m(2) 时,运行到foo()内部函数,发现变量 i 并不是foo()中的变量,于是就到外部函数func中寻找变量 i ,但此时外部的 for 已经循环完毕,最后的 i =3 。所以,每次
执行m(2),i 的值都是 3 ,因此,最终结果会是 [6, 6, 6, 6] 。
当在foo()中添加 i=i 后,即:
def func():
fun_list = []
for i in range(4):
def foo(x, i=i):
return x*i
fun_list.append(foo)
return fun_list
for m in func():
print m(2)
这样的话,for循环执行时,就已经把 i(0, 1, 2, 3) 的值传给了foo()函数,此时的 i 已经是foo()函数的内部变量,运行到foo()函数时,就不会到外部函数寻找变量 i ,直接运行
x*i(0, 1, 2, 3),因此最终结果会是 [0, 2, 4, 6] 。
关于 [lambda x: x*i for i in range(4)] 理解的更多相关文章
- fun = [lambda x: x*i for i in range(4)] 本质解析/原理,LEGB规则  闭包原理
		命名空间,闭包原理,参考点击本文 一.问题描述 fun = [lambda x: x*i for i in range(4)] for item in fun: print(item(1)) 上述式子 ... 
- lambda x:i*x for i in range(4)
		解决方法:冒号前添加接收 i 的变量 return [lambda x,i=i: i * x for i in range(4)] 
- 「C++11」Lambda 表达式
		维基百科上面对于 lambda 的引入是如下描述的: 在标准 C++,特别是当使用 C++ 标准程序库算法函数诸如 sort 和 find.用户经常希望能够在算法函数调用的附近定义一个临时的述部函数( ... 
- C++ 11 lambda
		转载:http://www.cnblogs.com/kedebug/p/3224561.html lambda 表达式的简单语法如下:[capture] (parameters) -> retu ... 
- Python 之 for循环中的lambda
		第一种 f = [lambda x: x*i for i in range(4)] (如果将x换成i,调用时候就不用传参数,结果都为3) 对于上面的表达式,调用结果: >>> f ... 
- Python特殊语法:filter、map、reduce、lambda [转]
		Python特殊语法:filter.map.reduce.lambda [转] python内置了一些非常有趣但非常有用的函数,充分体现了Python的语言魅力! filter(function, s ... 
- python中lambda函数
		1.lambda函数使用如下: lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右侧的是返回值 >>> g=lambda x,y:x*y>>> g(4 ... 
- Python filter,map,lambda,reduce,列表解析
		filter用法 filter(func,seq) 将seq的元素逐一代入func,通过func的返回值来判断是保留还是过滤 >>> def foo(x): return x> ... 
- lambda 的使用汇总
		d=lambda x:x+1print(d(10))lambda 相当于一个轻量函数返回 d=lambda x:x+1 if x>0 else "error"print(d( ... 
随机推荐
- 宁波Uber优步司机奖励政策(8月10号-16号)
			本周奖励: 8月10日-8月16日: 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://w ... 
- 转 Cobar使用文档(可用作MySQL大型集群解决方案)
			转自:http://blog.csdn.net/shagoo/article/details/8191346 最近好不容易抽空研究了下Cobar,感觉这个产品确实很不错(在文档方面比Amoeba强多了 ... 
- CDN 缓存策略(转)
			1.CDN加速原理 通过动态域名解析,网友的请求被分配到离自己最快的服务器.CDN服务器直接返回缓存文件或通过专线代理原站的内容. 网络加速+内容缓存,有效提供访问速度 2.CDN节点数量 ... 
- 2019年猪年海报PSD模板-第二部分
			14套精美猪年海报,免费猪年海报,下载地址:百度网盘,https://pan.baidu.com/s/1sH0U5oU-LQlaxnaWxPCrrg 
- QT 标题栏隐藏可拖拽
			这个也是我网上找到了 为了方便,记录一下 void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void ... 
- APP性能测试工具-GT(随身调)
			GT(随身调)是APP的随身调测平台,它是直接运行在手机上的“集成调测环境”(IDTE, Integrated Debug Environment).利用GT,仅凭一部手机,无需连接电脑,您即可对AP ... 
- Micro:bit 硬件架构介绍
			Micro:bit做为当红的少儿编程工具,这两年在编程教育领域越来越火.今天就从硬件架构开始,分享Micro:bit的相关主题. Microbit 硬件设计是根据ARM mbed技术所开发的应用IC及 ... 
- Django常用命令总结
			安装Django: pip install django 指定版本 pip3 install django==2.0 新建项目: django-admin.py startprject mysite ... 
- 【转】Bootstrap FileInput中文API整理
			Bootstrap FileInput中文API整理 这段时间做项目用到bootstrap fileinput插件上传文件,在用的过程中,网上能查到的api都不是很全,所以想着整理一份比较详细的文档, ... 
- [Clr via C#读书笔记]Cp16数组
			Cp16数组 一维数组,多维数组,交错数组:引用类型:P338的图非常的清楚地描述了值类型和引用类型在托管堆中的关系:越界检查: 数组初始化 数组初始化器: 四种写法 string[] names = ... 
