Python之匿名函数
在 python 编程中,除了常规的函数(也就是有 def 定义的),还有非常规的函数,它书写的非常简短,往往只有一行,它就是匿名函数--lambda。正确的使用匿名函数能够使我们的代码更加简洁,易读。
# 一、匿名函数基础
匿名函数的基础格式如下:
lambda argument1,argument2,...,argumentN: expression
其中 argumentN 是参数,expresssion 是函数主题表达式,类似于常规函数的如下写法:
def func(argument1,argument2,...,argumentN):
expression
2
我们可以看到匿名函数的关键字是 lambda,常规函数的关键字是 def,基本上匿名函数能做的事情常规函数都能做,那么为什么要使用匿名函数呢?先看下面这个例子:
## 用常规函数书写:
def func(x):
return x**2
func(3)
## 用匿名函数书写
func = lambda x: x**2
func(3)
2
3
4
5
6
7
8
你能看出有什么区别吗?
从直观上来看,两个函数的功能都是一样,但是它们的不同之处在于:
(1)、lambda 是一个表达式,并不是一个语句
所谓的表达式就是用一些“公式”去表达一些东西,比如我们常见的数学表达式: x+2 等,而语句则一定是完成某些功能,比如 x=2,完成是赋值等。
因此,lambda 能够出现在 python 语法不允许 def 出现的地方,比如 lambda 能够出现在列表中而 def 则不能,如下:
>>> [(lambda x: x**2)(x) for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2
再比如,lambda 可以作为一个函数的参数,如下:
>>> l = [(1, 20), (3, 0), (9, 10), (2, -1)]
>>> l.sort(key=lambda x: x[1]) ## 按列表中元组的第二个元素排序
>>> print(l)
[(2, -1), (3, 0), (9, 10), (1, 20)]
>>> l.sort(key=lambda x: x[0]) ## 按列表中元组的第一个元素排序
>>> print(l)
[(1, 20), (2, -1), (3, 0), (9, 10)]
>>>
2
3
4
5
6
7
8
常规函数 def,必须通过其定义的函数名进行调用,在调用之前必须先定义,而 lambda 只是一个表达式,返回的函数对象就不需要名字。
此外,lambda 作为一个表达式,它返回的一个值可以选择性的赋值给一个变量名,而对于 def,必须在在头部将一个新的函数赋值给一个变量,而不是把这个函数作为结果返回。
(2)、lambda 主体只是一个简单的单个表达式,并不是一个代码块
lambda 主体简单的就像放在 def 函数中的 return 语句中的代码一样,简单的将结果写成一个顺畅的表达式,而不是明确的返回。因为 lambda 仅限于表达式,它的功能比 def 小,连简单的 if 语句都不能使用,更不说函数的一些高级功能了。lambda 的设计初衷就是为了专注于简单任务,编辑简单的函数,而 def 是用来处理更复杂的任务的。
除了这些差别以外,lambda 也能处理和 def 某些同样的工作,比如:
## 用def创建函数
>>> def func(x, y, z): return x + y + z
...
>>> func(2, 3, 4)
9
## 用lambda创建函数
>>> f = lambda x, y, z: x + y +z
>>> f(2, 3, 4)
9
2
3
4
5
6
7
8
9
10
这里的 f 被赋值给 lambda 创建的函数对象,这也是 def 所完成的任务,只不过 def 是自动生成的。
默认参数在 lambda 中也能够使用,如下:
>>> f = lambda a="hello",b="world": a+b
>>> print(f)
<function <lambda> at 0x000001CAD4298C80>
>>> print(f())
helloworld
>>>
2
3
4
5
6
在 lambda 主体中的代码和 def 内的代码一样都遵循相同的作用于查找法则。lambda 表达式引入的一个本地作用域更像一个嵌套的 def 语句,将会自动从上层函数中、模块中 以及内置作用域中(通过 LEGB 法则)查找变量名。如下:
>>> def func():
... a = "hello"
... action = lambda x: a+x
... return action
...
>>> f = func("world")
>>> f("world")
'helloworld'
>>>
2
3
4
5
6
7
8
9
# 二、为什么使用匿名函数
通常来说,lambda 起到了一种函数速写的作用,允许在使用的代码内嵌入一个函数的定义。他们完全是可选的(你总是能够使用 def 来替代它们),但是你仅需要嵌入小段可执行代码的情况下它们会带来一个更简洁的代码结构,可以大大的简化代码的复杂度,提升代码的可读性。
通常来说,使用函数的目的不外乎下面两点:
(1)、减少重复代码;
(2)、模块化代码;
对于第一点,如果在代码中某些代码重复率非常高,那么我们就可以把这些相同的代码写成一个函数,并为它定义一个名字,方便调用。
对于第二点,主要是将一大段代码单独写成一个函数,方便调用,方便阅读,逻辑也会变的非常清晰。
不过如果某些函数非常非常简单,简单到一条语句就能完成,用 def 就感觉大材小用,这时候 lambda 就可以派上用场了。如下:
## def函数
def square(x):
return x**2
squared = map(square, [1, 2, 3, 4, 5])
## lambda函数
squared = map(lambda x: x**2, [1, 2, 3, 4, 5])
2
3
4
5
6
7
8
注:map(function, iterable),第一个参数是函数对象,第二个参数是一个可迭代对象。它表示对 iterable 的每一个元素都运用 function 这个函数。
可以看到匿名函数 lambda 的代码简洁的多,所以在一些简单代码的情况下,可以优先考虑使用 lambda。
作者:
本文链接:https://jokerbai.com
版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性-相同方式共享 4.0 国际 (CC-BY-NC-SA-4.0) 许可协议。转载请注明出处!
- 02
- 使用Zadig从0到1实现持续交付平台07-19
- 03
- 基于Jira的运维发布平台07-19