Python笔记之匿名函数:lambda

匿名函数:lambda

在Python中除了def语句之外还提供了另一种生成函数对象的表达式形式。(lambda是希腊字符λ,Haskell语言的符号就是λ,在这里我要安利大家都学习一下Haskell,这会对我们以后编程有很大的帮助)。lambda这个表达式创建1一个之后能够调用的函数,但是它返回了一个函数而不是将这个函数赋值给一个变量名。这也就是lambda为什么叫匿名函数的原因。实际上,lambda常常以一种行内进行函数定义的形式使用,或者用作推迟执行一些代码。

lambda表达式

lambda的一般表现形式是关键字lambda,之后是一个或多个参数,紧跟的是一个冒号,之后是一个表达式:

lambda argument1, argument2,... argumentN: expression using arguments
  • lambdas是一个表达式,而不是一个语句。所以lambda能够出现在Python语法不允许def出现的地方
  • lambda的主体的一个单一的表达式,而不是一个代码块。

除了这些差别,def和lambda都能够做同样种类的工作就像下面的例子所示:

#示例1
>>> def func(x, y, z):
...     return x + y + z
...
>>> func(3, 4, 5)
12


>>> f = lambda x, y, z: x + y + z
>>> f(3, 4, 5)
12

这里的f被赋值给一个lambda表达式创建的函数对象。

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

#示例2
>>> x = lambda a="I", b="Love" , c="You": a + b + c
>>> x()
'ILoveYou'
>>> x('e')
'eLoveYou'

为什么要使用lambda

一般来说,lambda起到了一种函数速写的作用,允许在使用的代码内嵌入一个函数的定义。

lambda通常用来编写跳转表,也就是行为的列表或字典,能够按照需要执行相应的动作。如示例3所示:

#示例3
L = [lambda x: x ** 2,
     lambda x: x ** 3,
     lambda x: x ** 4]

for f in L: 
    print(f(2))       #prints 4, 8, 16
    
print(L[0](3))        #prints 9

当需要把小段的可执行代码编写进def语句从语法上不能编写进的地方时,lambda表达式作为def的一种速写来说是最为有用的。如示例3,可以通过在列表常量中嵌入lambda表达式创建一个含有3个函数的列表。一个def是不会在列表常量中工作的,因为def是一个语句而不是一个表达式。对等的def代码可能需要在想要使用的环境之外有临时性函数名称和函数定义。

#示例4
def f1(x): return x ** 2
def f2(x): return x ** 3
def f3(x): return x ** 4

L = [f1, f2, f3]
for f in L: 
    print(f(2))          #prints 4, 8, 16
    
print(L[0](3))           #prints 9

不要让Python代码变得晦涩难懂

由于lambda的主体必须是单个表达式,由此仅能将有限的逻辑封装到一个lambda中。

例如,如果你想在lambda函数中进行print,那么就直接编写sys.stdout.write(str(x)+'\n')这个表达式,而不是使用print(x)这样的语句。类似的,要在一个lambda中嵌套逻辑,可以使用if/else三元表达式,或者对等的但需要有些技巧的and/or组合。

示例5
if a:
    b
else:
    c

b if a else c

((a and b) or c)

这些技巧最后在万不得已的情况下使用。不然就可能变成晦涩难懂的Python代码。

嵌套lambda和作用域

lambda是嵌套函数作用域查找的最大的受益者。例如示例6所示,lambda出现在def中,并且在上层函数调用的时候,嵌套的lambda能够获得到上层函数作用域中的变量名x的值。

示例6
>>> def action(x):
...     return (lambda y: x + y)
...
>>> act = action(99)
>>> act
<function action.<locals>.<lambda> at 0x000001CFBE6316A8>
>>> act(2)
101

如果我们把示例6中的def换成一个lambda:

示例7
>>> action = (lambda x: (lambda y: x + y))
>>> act = action(99)
>>> act(3)
102
>>> ((lambda x: (lambda y: x + y))(99))(4)
103

这里嵌套的lambda结构让函数在调用时创建了一个函数。无论以上哪种情况,嵌套的lambda代码都能够获取在上层lambda函数中的变量x。虽然这可以正常运行,但是这种代码让人相当费解。所有对于可读性的要求,通常来说最好避免使用嵌套lambda(可以装emmm为什么不用?)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值