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实现的生成自我描述脚本分享(很有意思的程序)
Jul 18 Python
Python常用模块用法分析
Sep 08 Python
MySQL中表的复制以及大型数据表的备份教程
Nov 25 Python
python中如何使用朴素贝叶斯算法
Apr 06 Python
python正则表达式之对号入座篇
Jul 24 Python
在python中pandas读文件,有中文字符的方法
Dec 12 Python
详解Python中pandas的安装操作说明(傻瓜版)
Apr 08 Python
Django Python 获取请求头信息Content-Range的方法
Aug 06 Python
Python文件操作模拟用户登陆代码实例
Jun 09 Python
Python分类测试代码实例汇总
Jul 23 Python
python 获取域名到期时间的方法步骤
Feb 10 Python
Python使用random模块实现掷骰子游戏的示例代码
Apr 29 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
php与flash as3 socket通信传送文件实现代码
2014/08/16 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
PHP常见字符串操作函数与用法总结
2019/03/04 PHP
php实现session共享的实例方法
2019/09/19 PHP
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
2010/05/06 Javascript
基于JQuery实现鼠标点击文本框显示隐藏提示文本
2012/02/23 Javascript
广泛收集的jQuery拖放插件集合
2012/04/09 Javascript
通过Javascript将数据导出到外部Excel文档的函数代码
2012/06/15 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
解析Node.js异常处理中domain模块的使用方法
2016/02/16 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
2016/08/08 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
详解node Async/Await 更好的异步编程解决方案
2018/05/10 Javascript
vuejs点击class变化的实例
2018/09/05 Javascript
react 应用多入口配置及实践总结
2018/10/17 Javascript
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
微信小程序实现watch监听
2020/06/04 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
深入理解javascript中的this
2021/02/08 Javascript
[47:31]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.12
2020/12/16 DOTA
py中的目录与文件判别代码
2008/07/16 Python
Python自动重试HTTP连接装饰器
2015/04/28 Python
Python base64编码解码实例
2015/06/21 Python
Python实现求两个csv文件交集的方法
2017/09/06 Python
python安装numpy和pandas的方法步骤
2019/05/27 Python
对pytorch中的梯度更新方法详解
2019/08/20 Python
意大利香水和彩妆护肤品购物网站:Ditano
2017/08/13 全球购物
Dune London官网:英国著名奢华鞋履品牌
2017/11/30 全球购物
Java提供了哪些企业应用编程接口
2015/02/13 面试题
软件测试有哪些?什么是配置项?
2012/02/12 面试题
生产厂厂长岗位职责
2013/12/25 职场文书
在校大学生个人的自我评价
2014/02/13 职场文书
工作迟到检讨书
2014/02/21 职场文书
学校教师师德师风承诺书
2015/04/28 职场文书
Win11安装升级时提示“该电脑必须支持安全启动”
2022/04/19 数码科技