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中设计模式之Decorator装饰器模式的要点
Mar 02 Python
python常见排序算法基础教程
Apr 13 Python
Python 用Redis简单实现分布式爬虫的方法
Nov 23 Python
安装python3的时候就是输入python3死活没有反应的解决方法
Jan 24 Python
python如何在列表、字典中筛选数据
Mar 19 Python
Python切片工具pillow用法示例
Mar 30 Python
Python面向对象程序设计之继承与多继承用法分析
Jul 13 Python
python特性语法之遍历、公共方法、引用
Aug 08 Python
python实现AES和RSA加解密的方法
Mar 28 Python
解决tensorflow打印tensor有省略号的问题
Feb 04 Python
如何利用python之wxpy模块玩转微信
Aug 17 Python
python如何编写类似nmap的扫描工具
Nov 06 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实现计算两个日期间隔的年、月、周、日数
2013/06/13 PHP
PHP会话控制:Session与Cookie详解
2014/09/27 PHP
Yii数据模型中rules类验证器用法分析
2016/07/15 PHP
php简单实现多维数组排序的方法
2016/09/30 PHP
THREE.JS入门教程(1)THREE.JS使用前了解
2013/01/24 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
js 对小数加法精度处理示例说明
2013/12/27 Javascript
jquery库文件略庞大用纯js替换jquery的方法
2014/08/12 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
node.js中的console.info方法使用说明
2014/12/09 Javascript
JavaScript中的对象序列化介绍
2014/12/30 Javascript
js关于命名空间的函数实例
2015/02/05 Javascript
JavaScript仿静态分页实现方法
2015/08/04 Javascript
jquery对象访问是什么及使用方法介绍
2016/05/03 Javascript
JS实现图片点击后出现模态框效果
2017/05/03 Javascript
详解Vue学习笔记进阶篇之列表过渡及其他
2017/07/17 Javascript
微信小程序实现图片懒加载的示例代码
2017/12/13 Javascript
小程序实现列表删除功能
2018/10/30 Javascript
jQuery实现的别踩白块小游戏完整示例
2019/01/07 jQuery
原生js实现商品筛选功能
2019/10/28 Javascript
vue iview实现动态新增和删除
2020/06/17 Javascript
JavaScript逻辑运算符相关总结
2020/09/04 Javascript
[53:52]OG vs EG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
Python Web框架Flask中使用百度云存储BCS实例
2015/02/08 Python
linux平台使用Python制作BT种子并获取BT种子信息的方法
2017/01/20 Python
使用keras实现孪生网络中的权值共享教程
2020/06/11 Python
Python抓包并解析json爬虫的完整实例代码
2020/11/03 Python
玖熙女鞋美国官网:Nine West
2016/10/06 全球购物
个人自我鉴定写法
2013/11/30 职场文书
美发活动策划书
2014/01/14 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
出国签证在职证明范本
2014/11/24 职场文书
2015社区健康教育工作总结
2015/05/20 职场文书
婚宴父母致辞
2015/07/27 职场文书
2016高校自主招生自荐信范文
2016/01/28 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书