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演示数型数据结构的教程
Apr 03 Python
Python bsddb模块操作Berkeley DB数据库介绍
Apr 08 Python
python实现将文本转换成语音的方法
May 28 Python
Python中http请求方法库汇总
Jan 06 Python
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
对numpy 数组和矩阵的乘法的进一步理解
Apr 04 Python
用Python将mysql数据导出成json的方法
Aug 21 Python
python数据挖掘需要学的内容
Jun 23 Python
Django 导出项目依赖库到 requirements.txt过程解析
Aug 23 Python
使用OpenCV实现仿射变换—旋转功能
Aug 29 Python
python绘制BA无标度网络示例代码
Nov 21 Python
在pycharm中实现删除bookmark
Feb 14 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
教你如何把一篇文章按要求分段
2006/10/09 PHP
joomla组件开发入门教程
2016/05/04 PHP
CI框架的安全性分析
2016/05/18 PHP
php的PDO事务处理机制实例分析
2017/02/16 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
php+mysql实现的无限分类方法类定义与使用示例
2020/05/27 PHP
css3实现背景模糊的三种方式
2021/03/09 HTML / CSS
优秀js开源框架-jQuery使用手册(1)
2007/03/10 Javascript
js调试工具 Javascript Debug Toolkit 2.0.0版本发布
2008/12/02 Javascript
使用JavaScript 实现对象 匀速/变速运动的方法
2013/05/08 Javascript
jquery点击页面任何区域实现鼠标焦点十字效果
2013/06/21 Javascript
JavaScript的递归之递归与循环示例介绍
2013/08/05 Javascript
调用innerHTML之后onclick失效问题的解决方法
2014/01/28 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
原生JavaScript编写canvas版的连连看游戏
2016/05/29 Javascript
移动开发之自适应手机屏幕宽度
2016/11/23 Javascript
jQuery使用ajax方法解析返回的json数据功能示例
2017/01/10 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
2017/06/09 jQuery
vue 开发一个按钮组件的示例代码
2018/03/27 Javascript
一篇文章带你浅入webpack的DLL优化打包
2020/02/20 Javascript
Python3实现的字典、列表和json对象互转功能示例
2018/05/22 Python
python使用PIL给图片添加文字生成海报示例
2018/08/17 Python
python 使用值来排序一个字典的方法
2018/11/16 Python
详解Python用户登录接口的方法
2019/04/17 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
2019/12/19 Python
使用Pandas将inf, nan转化成特定的值
2019/12/19 Python
Django ForeignKey与数据库的FOREIGN KEY约束详解
2020/05/20 Python
html5构建触屏网站之touch事件介绍
2013/01/07 HTML / CSS
阻止移动设备(手机、pad)浏览器双击放大网页的方法
2014/06/03 HTML / CSS
Speedo速比涛中国官方网站:全球领先泳装运动品牌
2018/04/24 全球购物
写给女朋友的检讨书
2014/01/28 职场文书
给校长的一封建议书
2014/03/12 职场文书
优秀班主任经验交流材料
2014/06/02 职场文书
万能检讨书
2015/01/27 职场文书
创业计划书之服装
2019/10/07 职场文书