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中精确输出JSON浮点数的方法
Apr 18 Python
python采用django框架实现支付宝即时到帐接口
May 17 Python
Python编程中对super函数的正确理解和用法解析
Jul 02 Python
利用ctypes提高Python的执行速度
Sep 09 Python
100行Python代码实现自动抢火车票(附源码)
Jan 11 Python
python3 http提交json参数并获取返回值的方法
Dec 19 Python
python matplotlib实现双Y轴的实例
Feb 12 Python
python批量图片处理简单示例
Aug 06 Python
python+Django实现防止SQL注入的办法
Oct 31 Python
pytorch中torch.max和Tensor.view函数用法详解
Jan 03 Python
python能做哪些生活有趣的事情
Sep 09 Python
Python基于爬虫实现全网搜索并下载音乐
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
php 启动报错如何解决
2014/01/17 PHP
WordPress中邮件的一些修改和自定义技巧
2015/12/15 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
QQ登录简单实现代码
2021/03/09 Javascript
js同时按下两个方向键
2007/12/01 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
2011/04/26 Javascript
JS截取字符串常用方法整理及使用示例
2013/10/18 Javascript
Javascript中对象继承的实现小例
2014/05/12 Javascript
给js文件传参数(详解)
2014/07/13 Javascript
javascript实现动态改变层大小的方法
2015/05/14 Javascript
学习JavaScript设计模式之状态模式
2016/01/08 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
2016/05/04 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
基于JavaScript实现前端文件的断点续传
2016/10/17 Javascript
利用vue + element实现表格分页和前端搜索的方法
2017/12/25 Javascript
vue 组件的封装之基于axios的ajax请求方法
2018/08/11 Javascript
小白教程|一小时上手最流行的前端框架vue(推荐)
2019/04/10 Javascript
react 组件传值的三种方法
2019/06/03 Javascript
VUE项目初建和常见问题总结
2019/09/12 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
2019/10/23 Javascript
[34:39]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第二局
2016/03/05 DOTA
Python中使用wxPython开发的一个简易笔记本程序实例
2015/02/08 Python
Python日期时间Time模块实例详解
2019/04/15 Python
Python3 实现串口两进程同时读写
2019/06/12 Python
浅谈keras中的目标函数和优化函数MSE用法
2020/06/10 Python
HTML5 device access 设备访问详解
2018/05/24 HTML / CSS
基于HTML5代码实现折叠菜单附源码下载
2015/11/27 HTML / CSS
HTML5 播放 RTSP 视频的实例代码
2019/07/29 HTML / CSS
豆腐の盛田屋官网:日本自然派的豆乳面膜、肥皂、化妆水、乳液等
2016/10/08 全球购物
澳大利亚玩具剧场:Toy Playhouse
2019/03/03 全球购物
美国在线面料商店:Fashion Fabrics Club
2020/01/31 全球购物
英文求职信写作小建议
2014/02/16 职场文书
干部作风建设工作总结
2014/10/29 职场文书
实习计划书范文
2015/01/16 职场文书
大学生活感想
2015/08/10 职场文书
React Fragment介绍与使用详解
2021/11/11 Javascript