理解Python中的Lambda函数

Python 中定义函数有两种方法,一种是用常规方式 def 定义,函数要指定名字,第二种是用 lambda 定义,不须要指定名字,称为 Lambda 函数。html

Lambda 函数又称匿名函数,匿名函数就是没有名字的函数,函数没有名字也行?固然能够啦。有些函数若是只是临时一用,并且它的业务逻辑也很简单时,就不必非给它取个名字不可。python

比如电影里面的群众演员,每每他们的戏份不多,最可能是陪衬主演,跑跑龙套,他们须要名字吗?不须要,由于他们仅仅只是临时出镜,下次可能就用不着了,因此犯不着费心思给他们每一个人编个号取个名字,毕竟取个优雅的名字是很费劲的事情。编程

先来看个简单 lambda 函数闭包

>>> lambda x, y : x+y
<function <lambda> at 0x102bc1c80>复制代码

x 和 y 是函数的两个参数,冒号后面的表达式是函数的返回值,你能一眼看出这个函数就是是在求两个变量的和,但做为一个函数,没有名字如何使用呢?这里咱们暂且给这个匿名函数绑定一个名字,这样使得咱们调用匿名函数成为可能app

>>> add = lambda x, y : x+y
>>> add
<function <lambda> at 0x102bc2140>
>>> add(1,2)
3复制代码

它等同于常规函数编程语言

>>> def add2(x, y):
...     return x+y
...
>>> add2
<function add2 at 0x102bc1c80>
>>> add2(1,2)
3复制代码

若是定义匿名函数,还要给它绑定一个名字的话,有点多此一举,一般是直接使用 lambda 函数。那么 lamdba 函数的正确使用场景在哪呢?函数式编程

一、函数式编程函数

尽管 Python 算不上是一门纯函数式编程语言,但它自己提供了不少函数式编程的特性,像 map、reduce、filter、sorted 这些函数都支持函数做为参数,lambda 函数就能够应用在函数式编程中。spa

请看题:一个整数列表,要求按照列表中元素的绝对值大小升序排列,你会怎么作?思考一分钟往下看.net

>>> list1 = [3,5,-4,-1,0,-2,-6]
>>> sorted(list1, key=lambda x: abs(x))
[0, -1, -2, 3, -4, 5, -6]复制代码

排序函数 sorted 支持接收一个函数做为参数,该参数做为 sorted 的排序依据,这里按照列表元素的绝对值进行排序,固然,我也能够用普通函数来实现:

>>> def foo(x):
...     return abs(x)
...
>>> sorted(list1, key=foo)
[0, -1, -2, 3, -4, 5, -6]复制代码

只不过是这种方式代码看起来不够 Pythonic 而已。

二、闭包

闭包自己是一个晦涩难懂的概念,它能够专门单独用一篇文章来介绍,不过在这里咱们能够简单粗暴地理解为闭包就是一个定义在函数内部的函数,闭包使得变量即便脱离了该函数的做用域范围也依然能被访问到。

来看一个用 lambda 函数做为闭包的例子。

>>> def my_add(n):
...     return lambda x:x+n
...
>>> add_3 = my_add(3)
>>> add_3(7)
10复制代码

这里的 lambda 函数就是一个闭包,在全局做用域范围中,add_3(7) 能够正常执行且返回值为10,之因此返回10是由于在 my_add 局部做用域中,变量 n 的值在闭包的做用使得它在全局做用域也能够被访问到。

换成常规函数也能够实现闭包,只不过是这种方式稍显啰嗦。

>>> def my_add(n):
...     def wrapper(x):
...         return x+n
...     return wrapper
...
>>> add_5 = my_add(5)
>>> add_5(2)
7复制代码

那么是否是任何状况 lambda 函数都要比常规函数更清晰明了呢?看这个例子:

f = lambda x: [[y for j, y in enumerate(set(x)) if (i >> j) & 1] for i in range(2**len(set(x)))]复制代码

这是一个返回某个集合的全部子集的 lambda 函数,你看明白了吗?我是很难一眼看出来

zen of python 中有这样一句话是 Explicit is better than implicit(明了胜于晦涩)。记住,若是用 lambda 函数不能使你的代码变得更清晰时,这时你就要考虑使用常规的方式来定义函数。


5月4日晚上8点,我在CSDN直播《爬虫入门与实践》,有兴趣的能够去看看,须要优惠的能够在公众号留言,暗号「福利」。

同步发表:foofish.net/lambda.html
公众号 Python之禅 (id:VTtalk),分享 Python 等技术干货

相关文章
相关标签/搜索