lambda函数详细介绍(Python)

本文详细介绍了Python中的lambda函数,包括其定义、语法形式、与def关键字的区别,以及如何与map、filter、reduce等函数结合使用。同时,还讨论了lambda函数的使用场景及其局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

在Python中,除了使用def关键字声明普通函数外,还提供了一种使用表达式生成函数对象的形式。由于它与LISP语言中的一个工具很相似,所以称为lambda。

lambda函数也叫匿名函数,即没有具体名称的函数,它允许快速定义单行函数,可以用在任何需要函数的地方。

lambda的语法形式如下:
  lambda arg1, arg2, …, argN : expression
首先是关键字lambda;随后是一个或多个参数,其形式与用def定义函数的参数形式类似;紧跟的是一个冒号;最后是一个表达式,表达式使用的参数需要在冒号左边进行定义,表达式的结果即是该匿名函数的结果。
lambda语句构建的其实是一个函数对象,其示例如下所示:

>>> g = lambda x: x**2
>>> g
<function <lambda> at 0x7f36cba80c08>

与def的联系和区别

联系

由lambda表达式所返回的函数对象与由def创建并复制后的函数对象工作起来是完全一样的。
用def定义的求某个数的平方的函数f的代码如下:

>>> def f(x):
...     return x**2
... 
>>> f(4)
16

可使用lambda实现上述函数的功能

>>> g = lambda x: x**2
>>> g(4)
16

默认参数也能够在lambda参数中使用,就像在def中使用一样。

>>> x = (lambda a="hello", b=",", c="world": a + b + c)
>>> x()
'hello,world'
>>> x("hi")
'hi,world'

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

>>> def test(title="Sir"):
...     action =  (lambda x: title + ' ' + x)
...     return action
... 
>>> act = test()
>>> act('robin')
'Sir robin'

区别

lambda和def具有如下区别:

  1. def定义的普通函数是有函数名称的,而lambda定义的函数并没有函数名称,因此也被称为匿名函数。
  2. lambda会返回一个函数对象,但不会为这个对象赋予一个标识符,而def则会把函数对象赋值给一个变量即函数名。
  3. lambda只是一个表达式,而def则是一个语句。 因为这一点,lambda能够出现在Python语法不允许def出现的地方,例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性的赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。
  4. lambda是一个为编写简单的函数而设计的,而def用来处理更大的任务。lambda的主体是一个单个的表达式即冒号“:”后面只能有一个表达式,而def可以有多个即构成一个代码块。lambda仅限于表达式,使得其功能通常要比def少得多:只能够在lambda主体中将有限的逻辑封装进去,像if或for或print等语句都不能在lambda中使用,但是可以在def中使用。
  5. lambda函数不能共享给别的程序调用,def可以。

lambda与def定义的普通函数相比,只是省去了函数名称而已,而且这样的匿名函数又不能在别的地方调用。但是lambda还是具有如下优点:

  1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
  2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。
  3. 使用lambda在某些时候让代码更容易理解。

与map/filter/reduce的联合使用

使用lambda定义的匿名函数可与Python提供的map、filter、reduce等全局函数结合使用,其示例如下所示:

>>> list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> map(lambda x: x * 2, list)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
>>> filter(lambda x: x % 3 == 0, list)
[3, 6, 9]
>>> reduce(lambda x, y: x + y, list)
55

使用场景

替换形式

虽然可以在Python程序中使用lambda以达到一定的简洁程度,但是却并不一定非要使用lambda。

在对象遍历处理方面,Python语言提供的for..in..if语法非常强大,并且在易读性上胜过了lambda,比如在上面的map例子可以修改为如下:

>>> [x * 2 for x in list]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

上面的filter例子可以修改为如下:

>>> [x for x in list if x % 3 == 0]
[3, 6, 9]

所以,什么时候使用lambda,什么时候不用,需要具体情况具体分析,只要表达的意图清晰就好。一般情况下,如果for..in..if能做的,尽量不要使用lambda。

常见问题

参数问题

如果想创建一个函数数组fs=[f_0, …, f_n],其中f_i(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

显然,这样定义的lambda函数并不能正确实现预期的功能。问题其实出在变量i上,lambda中的i使用的是匿名函数外的全局变量,即使用到的i的值都为9。可将代码修改为如下:

>>> fs = [(lambda n, i=i : i + n) for i in range(10)]
>>> fs[3](4)
7
>>> fs[4](4)
8

lambda的例子
lambda的使用情况及不适用情况

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值