全文都是抄来的html
Python中的lambda的“一个语法,三个特性,四个用法,一个争论”。python
在Python中,lambda的语法是惟一的。其形式以下:web
其中,lambda是Python预留的关键字,argument_list和expression由用户自定义。具体介绍以下。express
这里的expression是一个关于参数的表达式。表达式中出现的参数须要在argument_list中有定义,而且表达式只能是单行的。如下都是合法的表达式:编程
这里的 lambda argument_list: expression
表示的是一个函数。这个函数叫作lambda函数。api
lambda函数有以下特性:闭包
下面是一些lambda函数示例:app
因为lambda语法是固定的,其本质上只有一种用法,那就是定义一个lambda函数。在实际中,根据这个lambda函数应用场景的不一样,能够将lambda函数的用法扩展为如下几种:函数
将lambda函数赋值给一个变量,经过这个变量间接调用该lambda函数。学习
将lambda函数赋值给其余函数,从而将其余函数用该lambda函数替换。
将lambda函数做为其余函数的返回值,返回给调用者。
举个栗子
优势1,2 就不说了,很容易理解,关于第三个,例如当在一个类中实现的方法不多时,或者仅有一个方法时,就能够选择使用闭包。
举个栗子
闭包的概念差很少就是这样了。
上述式子的输出结果: 预计结果为:0, 2, 4, 6 实际输出为:3, 3, 3, 3
lambda x: x*i
为内层(嵌)函数,他的命名空间中只有 {'x': 1} 没有 i , 因此运行时会向外层函数(这儿是列表解析式函数 [ ])的命名空间中请求 i 而当列表解析式运行时,列表解析式命名空间中的 i 通过循环依次变化为 0-->1-->2-->3 最后固定为 3 , 因此当 lambda x: x*i
内层函数运行时,去外层函数取 i 每次都只能取到 3lambda x: x*i
增长参数,命名空间中有了用来存储每次的 i , 即改为 [lambda x, i=i: x*i for i in range(4)]
这样每一次,内部循环生成一个lambda 函数时, 都会把 --i--做为默认参数传入lambda的命名空间 循环4次实际lambda表达式为: 第一次:lambda x, i=0 第二次:lambda x, i=1 第三次:lambda x, i=2 第四次:lambda x, i=3
函数fun = [lambda x: x*i for i in range(4)]
等价于:以下函数
查看该函数命名空间及 I 值变化:
#运行结果为:为了排版美观,我已将输出lambda_函数地址更名为:lam函数1 2 3
能够看见:就像上面所说的:四次循环中外层函数命名空间中的 i 从 0-->1-->2-->3 最后固定为3, 而在此过程当中内嵌函数-Lambda函数中由于没有定义 i 因此只有Lambda 函数动态运行时, 在本身命名空间中找不到 i 才去外层函数复制 i = 3 过来,结果就是全部lambda函数的 i 都为 3, 致使得不到预计输出结果:0,1,2,3 只能获得 3, 3, 3, 3
给内层函数 lambda增长默认参数,命名空间中有了用来存储每次的 i , 即改为 `def lambda(x, i=i) :` 这样每一次, 内部循环生成一个lambda 函数时,都会把 i 做为默认参数传入lambda的命名空间 循环4次实际lambda表达式为: 第一次:lambda( x, i=0) 第二次:lambda(x, i=1) 第三次:lambda(x, i=2) 第四次:lambda(x, i=3)
这样咱们就能获得预计的结果:0, 1, 2, 3
只有函数、类、模块会产生做用域,代码块不会产生做用域。做用域按照变量的定义位置能够划分为4类:
python解释器查找变量时,会按照顺序依次查找局部做用域--->嵌套做用域--->全局做用域--->内建做用域,在任意一个做用域中找到变量则中止查找,全部做用域查找完成没有找到对应的变量,则抛出 NameError: name 'xxxx' is not defined的异常。
人生还有意义。那必定是还在找存在的理由