From pixabay

在python编程中,除了常规的函数(也就是有def定义的),还有非常规的函数,它书写的非常简短,往往只有一行,它就是匿名函数--lambda。正确的使用匿名函数能够使我们的代码更加简洁,易读。

一、匿名函数基础

匿名函数的基础格式如下:

lambda argument1,argument2,...,argumentN: expression

其中argumentN是参数,expresssion是函数主题表达式,类似于常规函数的如下写法:

def func(argument1,argument2,...,argumentN):

    expression

我们可以看到匿名函数的关键字是lambda,常规函数的关键字是def,基本上匿名函数能做的事情常规函数都能做,那么为什么要使用匿名函数呢?先看下面这个例子:

# 用常规函数书写:

def func(x):

    return x**2

func(3)    

# 用匿名函数书写

func = lambda x: x**2

func(3)

你能看出有什么区别吗? 从直观上来看,两个函数的功能都是一样,但是它们的不同之处在于: (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]

再比如,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)]

>>>

常规函数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

这里的f被赋值给lambda创建的函数对象,这也是def所完成的任务,只不过def是自动生成的。 默认参数在lambda中也能够使用,如下:

>>> f = lambda a="hello",b="world": a+b

>>> print(f)

<function <lambda> at 0x000001CAD4298C80>

>>> print(f())

helloworld

>>>

在lambda主体中的代码和def内的代码一样都遵循相同的作用于查找法则。lambda表达式引入的一个本地作用域更像一个嵌套的def语句,将会自动从上层函数中、模块中 以及内置作用域中(通过LEGB法则)查找变量名。如下:

>>> def func():

...     a = "hello"

...     action = lambda x: a+x

...     return action

...

>>> f = func("world")

>>> f("world")

'helloworld'

>>>

二、为什么使用匿名函数

通常来说,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])

注:map(function, iterable),第一个参数是函数对象,第二个参数是一个可迭代对象。它表示对iterable的每一个元素都运用function这个函数。 可以看到匿名函数lambda的代码简洁的多,所以在一些简单代码的情况下,可以优先考虑使用lambda。