Python的lambda匿名函数的简单介绍


Posted in Python onApril 25, 2013

lambda函数也叫匿名函数,即,函数没有具体的名称。先来看一个最简单例子:

def f(x):
return x**2
print f(4)

Python中使用lambda的话,写成这样
g = lambda x : x**2
print g(4)

lambda表达式在很多编程语言都有对应的实现。比如C#:

var g = x => x**2
Console.WriteLine(g(4))

那么,lambda表达式有什么用处呢?很多人提出了质疑,lambda和普通的函数相比,就是省去了函数名称而已,同时这样的匿名函数,又不能共享在别的地方调用。其实说的没错,lambda在Python这种动态的语言中确实没有起到什么惊天动地的作用,因为有很多别的方法能够代替lambda。同时,使用lambda的写法有时显得并没有那么pythonic。甚至有人提出之后的Python版本要取消lambda。

回过头来想想,Python中的lambda真的没有用武之地吗?其实不是的,至少我能想到的点,主要有:

1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。

2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。

3. 使用lambda在某些时候让代码更容易理解。

lambda基础
lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值。lambda语句构建的其实是一个函数对象,见证一下:

g = lambda x : x**2
print g
<function <lambda> at 0x00AFAAF0>

C#3.0开始,也有了lambda表达式,省去了使用delegate的麻烦写法。C#中的lambda表达式关键字是=>,看下面的一个例子:
var array = new int[] {2, 3, 5, 7, 9};
var result = array.Where(n => n > 3); // [5, 6, 9]

C#使用了扩展方法,才使得数组对象拥有了像Where,Sum之类方便的方法。Python中,也有几个定义好的全局函数方便使用的,他们就是filter, map, reduce。

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>>
>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>>
>>> print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>>
>>> print reduce(lambda x, y: x + y, foo)
139

非lambda不可?
上面例子中的map的作用,和C#的Where扩展方法一样,非常简单方便。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。比如上面map的例子,可以写成:

print [x * 2 + 10 for x in foo]

非常的简洁,易懂。filter的例子可以写成:
print [x for x in foo if x % 3 == 0]

同样也是比lambda的方式更容易理解。

所以,什么时候使用lambda,什么时候不用,需要具体情况具体分析,只要表达的意图清晰就好。一般情况下,如果for..in..if能做的,我都不会选择lambda。

lambda broken?
在数学教学中,经常会使用到lambda,比如有一位老兄就遇到这样一个问题。他想创建一个函数数组fs=[f0,...,f9] where fi(n)=i+n. 于是乎,就定义了这么一个lambda函数:

fs = [(lambda n: i + n) for i in range(10)]

但是,奇怪的是,
>>> fs[3](4)
13
>>> fs[4](4)
13
>>> fs[5](4)
13

结果并没有达到这位老兄的预期,预期的结果应该是:
>>> fs[3](4)
7
>>> fs[4](4)
8
>>> fs[5](4)
9

问题其实出在变量i上。上面的代码换个简单的不使用lambda的缩减版本:
i = 1
def fs(n):
return n + i
print fs(1) # 2
i = 2
print fs(1) # 3

可见,上面没有达到预期的原因是lambda中的i使用的是匿名函数外的全局变量。修改一下:
fs = [(lambda n, i=i : i + n) for i in range(10)]
>>> fs[3](4)
7
>>> fs[4](4)
8
>>> fs[5](4)
9
Python 相关文章推荐
python encode和decode的妙用
Sep 02 Python
使用PYTHON接收多播数据的代码
Mar 01 Python
python实现html转ubb代码(html2ubb)
Jul 03 Python
Python读写Json涉及到中文的处理方法
Sep 12 Python
python中Matplotlib实现绘制3D图的示例代码
Sep 04 Python
Python字典及字典基本操作方法详解
Jan 30 Python
查看python安装路径及pip安装的包列表及路径
Apr 03 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
Apr 29 Python
Python使用type关键字创建类步骤详解
Jul 23 Python
python3.6生成器yield用法实例分析
Aug 23 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
Jan 20 Python
pandas将list数据拆分成行或列的实现
Dec 13 Python
python批量下载图片的三种方法
Apr 22 #Python
如何运行Python程序的方法
Apr 21 #Python
python读取注册表中值的方法
Apr 08 #Python
重命名批处理python脚本
Apr 05 #Python
Python编写的com组件发生R6034错误的原因与解决办法
Apr 01 #Python
Python中用Ctrl+C终止多线程程序的问题解决
Mar 30 #Python
python利用hook技术破解https的实例代码
Mar 25 #Python
You might like
第十一节 重载 [11]
2006/10/09 PHP
ThinkPHP实现多数据库连接的解决方法
2014/07/01 PHP
PHP正则表达式之捕获组与非捕获组
2015/11/06 PHP
thinkphp表单上传文件并将文件路径保存到数据库中
2016/07/28 PHP
php unicode编码和字符串互转的方法
2020/08/12 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
innerHTML与jquery里的html()区别介绍
2012/10/12 Javascript
5秒后跳转到另一个页面的js代码
2013/10/12 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/25 Javascript
javascript实现微信分享
2014/12/23 Javascript
jquery判断密码强度的验证代码
2020/04/22 Javascript
JavaScript实现ASC转汉字及汉字转ASC的方法
2016/01/23 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
jquery滚动条插件(可以自定义)
2016/12/11 Javascript
微信小程序左滑删除效果的实现代码
2017/02/20 Javascript
JS实现浏览器打印、打印预览示例
2017/02/28 Javascript
axios取消请求的实践记录分享
2018/09/26 Javascript
three.js实现圆柱体
2018/12/30 Javascript
Angular CLI 使用教程指南参考小结
2019/04/10 Javascript
vue实现公告栏文字上下滚动效果的示例代码
2020/06/16 Javascript
python生成ppt的方法
2018/06/07 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
英国知名的皮手套品牌:Dents
2016/11/13 全球购物
澳大利亚工具仓库:Tools Warehouse
2018/10/15 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
乡镇庆八一活动方案
2014/02/02 职场文书
企业晚会策划方案
2014/05/29 职场文书
计算机毕业生自荐信
2014/06/12 职场文书
效能风暴心得体会
2014/09/04 职场文书
毕业生个人自荐书
2015/03/05 职场文书
公司董事任命书
2015/09/21 职场文书
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
2021/04/01 PHP
使用jpa之动态插入与修改(重写save)
2021/11/23 Java/Android