关于 [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优步司机奖励政策(1月19日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 成都Uber优步司机奖励政策(1月16日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- SpringBoot-04:SpringBoot在idea中的俩种创建方式
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 创建SpringBoot工程有很多种方式,我只讲俩种最为常见的 一,依托springboot官网提供的模板.( ...
- git 操作几个命令
git clone ssh://lijianfeng@192.168.1.246:29418/GMGameSDK压栈:git stash查状态:git status切换到要修改的提交:git reb ...
- 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...
- Git 与 GitHub
Git 这个年代,不会点Git真不行啦,少年别问问什么,在公司你就知道了~ Git是一个协同开发的工具,主要作用是进行版本控制,而且还能自动检测代码是否发生变化. 一. 安装 下载地址:https:/ ...
- Python2快速入门教程,只需要这十五张图片就够了!
今天给大家分享的教程是适用于Python 2.7,但它可能适用于Python 2.Python 2.7将停止在2020中的支持. 与Python 2.7和3兼容的Python代码是完全可能的.通过使用 ...
- 【递归入门】组合+判断素数:dfs(递归)
题目描述 已知 n 个整数b1,b2,…,bn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12, ...
- Redhat linux 安装SVN服务器 CollabNetSubversionEdge
请仔细阅读安装包自带的readme文件! ================================================= 1. 先去官网,找安装包: http://subversi ...
- qt qchart缩放后坐标轴间隔取整
使用qt的qchart显示数据曲线,坐标轴QValueAxis可以设置刻度间隔数量,但每个刻度的数值是根据坐标的极值除以间隔数量得到的,不一定是整数,导致曲线控件的显示刻度不适合观察. 如图: 纵坐标 ...