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 相关文章推荐
PyMongo安装使用笔记
Apr 27 Python
详解Python的Django框架中的Cookie相关处理
Jul 22 Python
python 常用的基础函数
Jul 10 Python
python遍历文件夹,指定遍历深度与忽略目录的方法
Jul 11 Python
Python实现的多进程拷贝文件并显示百分比功能示例
Apr 09 Python
python requests使用socks5的例子
Jul 25 Python
python下载库的步骤方法
Oct 12 Python
关于ZeroMQ 三种模式python3实现方式
Dec 23 Python
Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现
Apr 22 Python
keras处理欠拟合和过拟合的实例讲解
May 25 Python
Python和Bash结合在一起的方法
Nov 13 Python
Python基础之元组与文件知识总结
May 19 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
星际争霸秘籍
2020/03/04 星际争霸
上海无线电三厂简史修改版
2021/03/01 无线电
php自动加载autoload机制示例分享
2014/02/20 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
有关DOM元素与事件的3个谜题
2010/11/11 Javascript
Javascript正则控制文本框只能输入整数或浮点数
2014/09/02 Javascript
jQuery实现的支持IE的html滑动条
2015/03/16 Javascript
好好了解一下Cookie(强烈推荐)
2016/06/14 Javascript
jQuery实现碰到边缘反弹的动画效果
2018/02/24 jQuery
解决iview打包时UglifyJs报错的问题
2018/03/07 Javascript
解决layui 复选框等内置控件不显示的问题
2018/08/14 Javascript
微信小程序tabBar 返回tabBar不刷新页面
2019/07/25 Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
2019/10/23 Javascript
jquery插件懒加载的示例
2020/10/24 jQuery
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
[03:42]2014DOTA2国际邀请赛 第三日比赛排位扑朔迷离
2014/07/12 DOTA
[00:17]天涯墨客一技能展示
2018/08/25 DOTA
[01:20:37]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python pickle模块用法实例分析
2015/05/27 Python
详解Python3中yield生成器的用法
2015/08/20 Python
python在线编译器的简单原理及简单实现代码
2018/02/02 Python
python+opencv实现高斯平滑滤波
2020/07/21 Python
Python3.5集合及其常见运算实例详解
2019/05/01 Python
Python类如何定义私有变量
2020/02/03 Python
keras实现基于孪生网络的图片相似度计算方式
2020/06/11 Python
通过代码实例解析Pytest运行流程
2020/08/20 Python
详解numpy1.19.4与python3.9版本冲突解决
2020/12/15 Python
去除python中的字符串空格的简单方法
2020/12/22 Python
Timberland俄罗斯官方网上商店:全球领先的户外品牌
2020/03/15 全球购物
大一新生军训时的自我评价分享
2013/12/05 职场文书
竞选学委演讲稿
2014/09/13 职场文书
放假通知
2015/04/14 职场文书
迎新晚会主持词开场白
2015/05/28 职场文书
2015年工商局个人工作总结
2015/07/23 职场文书
golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
2021/05/05 Golang
一文带你探究MySQL中的NULL
2021/11/11 MySQL