我们知道在 Python 中定义一个函数使用 def
关键字。实际上,Python 中还有另一种定义函数的语法,使用 lambda
关键字即可定义一个短小的 匿名函数
。
lambad 表达式的定义语法
下面是一个使用 lambda
关键字定义 匿名函数
的简单示例,用于对传进来的两个参数进行求和:
1 | lambda x, y: x + y |
其中,冒号(:
)左侧的 x, y
变量分别是 匿名函数
的两个参数,而冒号(:
)右侧的表达式 x + y
将作为 匿名函数
的 返回值
进行返回(这个过程是自动的,无需显式的写 return
语句进行返回,写了反而会报错)。
那么该如何调用这个 匿名函数
呢?请看下面的代码:
1 | lambda x, y: x + y)(2, 3) ( |
要想调用 匿名函数
,只需要在 匿名函数
最外层给它加上一个括号,然后就能像调用普通函数一样的语法,使用 (参数1, 参数2)
的形式调用它了。 在 Python 控制台执行以上代码可以得到正确的求和结果 5
。
以上的 匿名函数
的定义和执行过程,如果使用普通函数来完成,代码如下:
1 | def add(x, y): |
经过对比,我们可以发现,使用 def
的普通函数需要 3 行才能搞定的事情,使用 匿名函数
只需要 1 行就可以了。
用 lambda
关键字定义的 匿名函数
只是一个 Python 的语法糖,它与 def
关键字定义的函数并无本质区别。不过需要注意的是,在 匿名函数
中,只允许定义单一的表达式,而不能定义其他语句,并且表达式的结果会被当作函数的返回值进行返回,因此 匿名函数
也被称作 lambda 表达式
。
在 Python 中函数也是对象,因此我们可以将函数赋值给一个变量,然后通过这个变量来调用函数。
1 | lambda x, y: x + y add = |
事实上,这种通过变量引用来调用 匿名函数
的方式才是我们在实际编码过程中用的更多的方式。
lambda 表达式的应用
下面我来介绍一下 匿名函数
的应用场景。
假如我们有一个由 元组
组成的 列表
,我们需要对其进行排序,此时可以使用 Python 内置的 sorted
函数:
1 | 1, 'Python'), (3, 'JavaScript'), (2, 'Go')] li = [( |
可以看到,对 列表
使用 sorted
函数对其进行排序以后,其排序顺序是根据每个元组中第一个元素的大小进行排序的。那么如果我们想要根据元组的第二个元素按照字母顺序进行排序呢?这个时候,就可以用到 匿名函数
了。
1 | 1, 'Python'), (3, 'JavaScript'), (2, 'Go')] li = [( |
sorted
函数接收一个参数 key
可以用来作为排序对象的排序依据,这个参数必须是一个可调用对象,所以通常我们可以定义一个函数来处理。但是一般来说这样的函数只会使用一次,并且这个示例所需的函数足够短小,此时正是使用 匿名函数
的最佳时机。
同 def
关键字定义的函数一样,使用 lambda
关键字定义的 匿名函数
同样支持嵌套。下面展示一个 lambda 表达式
版本的 闭包函数
。
1 | lambda x: lambda y: x + y make_add = |
我在此必须强调一点,这种嵌套的写法虽然语法上是支持的,但在实际工作中千万不要这样来写,如果项目中充斥着大量的这种代码,那么这个项目将变得难以维护。给出这个示例,我只是想鼓励大家对于一个新接触的语法可以多进行尝试,这样才能进步得更快,同时获得更多的乐趣。
在 Python 中对于 匿名函数
的使用,我的观点是,只有需要一个非常短小且只在一处调用的函数时才使用,不然代码将会变得花里胡哨而难以维护。
匿名函数
的诸多限制至使它只能完成一个简单的工作,不过这也正是 匿名函数
的初衷,至于许多繁琐的工作,还是交给 def
去做吧。