Python之旅——lambda表达式

鸣谢answer3lin大大~
因为自己才疏学浅,所以很多知识点都是依靠前辈的blog才完善起来的
如果有错误就麻烦路过的大大们给我指出啦

什么是 l a m b d a lambda lambda表达式?

l a m b d a lambda lambda表达式是用来定义匿名函数的。
顾名思义,匿名函数就是没有具体名称的函数

强调强调!ta 一个函数,只不过没有特定名称!

如果说 d e f def def创建的函数是白道,那么 l a m b d a lambda lambda表达式就像是黑道:行事简单粗暴,但是异常高效

使用 l a m b d a lambda lambda表达式可以节省定义函数过程
当我们遇到一些简单重复性操作时,就没有必要专门定义一个函数,使用 l a m b d a lambda lambda表达式可以使代码更加精简美观

这样一来,一方面我们可以解决给函数起名字这个头疼的问题
另一方面也可以简化代码,提高代码的可读性,当不再使用该匿名函数的时候,内存会自动释放其占据的空间,非常的经济实惠
(最重要的一点,就是可以让那些初学者读不懂你的代码,帮助你成功步入Py大神的殿堂,简直美汁汁~)

讲真我觉得 l a m b d a lambda lambda表达式的存在非常符合我写代码的一贯风格:中规中矩中隐藏着一丝跳脱,跳脱中不乏一丝诡谲(大雾)


l a m b d a lambda lambda表达式原型

lambda argument_list : expression

a r g u m e n t _ l i s t argument\_list argument_list是参数列表,ta的结构与Python中函数的参数列表是一样的 (输入)
e x p r e s s i o n expression expression是一个关于参数的表达式,表达式中出现的参数需要在 a r g u m e n t _ l i s t argument\_list argument_list中有定义,并且表达式只支持单行 (输出)

注意:

  • l a m b d a lambda lambda函数:又称 " 匿名函数 "
  • l a m b d a lambda lambda函数有输入和输出:输入是传入到参数列表 a r g u m e n t _ l i s t argument\_list argument_list的值,输出是根据表达式 e x p r e s s i o n expression expression计算得到的值
  • l a m b d a lambda lambda函数功能简单:单行 e x p r e s s i o n expression expression决定了 l a m b d a lambda lambda函数不可能完成复杂的逻辑

基本用法及举例

( 一 ) 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数
f = lambda x, y: x*y
# 函数输入是x和y,输出是它们的积x*y

u = lambda:None
# 函数没有输入参数,输出是None

g = lambda *args: sum(args)
# 输入是任意个数的参数,输出是它们的和(隐性要求是输入参数必须能够进行加法运算)

v = lambda **kwargs: 1
# 输入是任意键值对参数,输出是1

实际上我们也可以直接调用 l a m b d a lambda lambda函数
(lambda x : x+3)(3)
因为匿名函数是没有名字的,只由函数体和参数组成,直接使用小括号将函数体括起来,即可执行
函数体后面加上小括号,就是给匿名函数传参


而且普通函数所支持的参数的变化, l a m b d a lambda lambda函数也支持
比如默认参数:(lambda x,y=3: x+y)(5)

( 二 ) 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换

例如,为了把标准库time中的函数 s l e e p sleep sleep的功能屏蔽(Mock),我们可以在程序初始化时调用:time.sleep=lambda x:None
这样,在后续代码中调用 t i m e time time库的 s l e e p sleep sleep函数将不会执行原有的功能
例如,执行time.sleep(3)时,程序不会休眠3秒钟,而是什么都不做

( 三 ) 将lambda函数作为其他函数的返回值,返回给调用者

这时,lambda函数实际上是定义在某个函数内部的函数,称之为内(嵌)函数
这是什么?这是闭包啊!

def outer(x):
	def inner(y):
		return x+y
	return inner

>>> f = outer(3)
>>> f(5)
8

####################### 等价写法

def outer(x):
	return lambda y : x+y

>>> f = outer(3)
>>> f(5)
8

你会发现,这样写真的好简单!
在一行内既解决了函数定义,也完成了返回函数引用的任务

( 四 ) 将lambda函数作为参数传递给其他函数。

部分Python内置函数接收函数作为参数
典型的此类内置函数有:

  • f i l t e r filter filter函数
    此时 l a m b d a lambda lambda函数用于指定过滤列表元素的条件
newlist = filter(lambda x : x%2==1 , [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(list(newlist))
# 输出要转成列表类型

# 选出奇数
[1,3,5,7,9]
  • s o r t e d sorted sorted函数
    此时 l a m b d a lambda lambda函数用于指定对列表中所有元素进行排序的准则
newlist = sorted([1,2,3,4,5,6,7,8,9] , key = lambda x : abs(5-x))
print(list(newlist))

# 按照元素与5距离从小到大进行排序
[5, 4, 6, 3, 7, 2, 8, 1, 9]
  • m a p map map函数
    此时 l a m b d a lambda lambda函数用于指定对列表中每一个元素的共同操作
newlist = map(lambda x: x+1, [1, 2,3])
print(list(newlist))

# 将列表中的元素分别加1
[2, 3, 4]
  • r e d u c e reduce reduce函数
    此时 l a m b d a lambda lambda函数用于指定列表中两两相邻元素的结合条件
reduce(lambda x, y: x+y, [1,2,3,4,5])

# 计算列表和
15

需要注意

  • l a m b d a lambda lambda函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值

  • l a m b d a lambda lambda函数不能包含命令,包含的表达式不能超过一个

  • l a m b d a lambda lambda函数只能包含表达式,不能出现输出,条件判断,循环等语法结构
    如果发现需要使用这些语法结构时,建议直接定义函数

  • l a m b d a lambda lambda函数直接返回这一句表达式的值

  • l a m b d a lambda lambda表达式只能写在一行上,所以也有人也叫ta单行函数

  • 使用 l a m b d a lambda lambda关键字定义匿名函数

  • 参数列表不需要使用括号

  • l a m b d a lambda lambda并不会带来程序运行效率的提高,只会使代码更简洁

  • d e f def def中用 r e t u r n return return可以返回的内容可以放在 l a m b d a lambda lambda后面,不能用 r e t u r n return return返回的则不能定义在 l a m b d a lambda lambda

  • l a m b d a lambda lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数

  • l a m b d a lambda lambda函数不同于C或C++的内联函数,后者的目的是调用小型函数时不占用栈内存从而提高运行效率

  • 鉴于可读性方面的考虑,应避免使用嵌套 l a m b d a lambda lambda


l a m b d a lambda lambda表达式与命名函数的区别

  • l a m b d a lambda lambda不创建接收变量

d e f def def创建的方法是有名称的,而 l a m b d a lambda lambda没有,可以立刻传递(无需变量)
l a m b d a lambda lambda会创建一个函数对象,但不会把这个函数对象赋给一个标识符,而 d e f def def则会把函数对象赋值给一个变量(函数名)

  • l a m b d a lambda lambda只是一个表达式,而 d e f def def则是一个语句

i f if if f o r for for p r i n t print print等语句不能用于 l a m b d a lambda lambda
简单来说:在 d e f def def中用 r e t u r n return return可以返回的内容可以放在 l a m b d a lambda lambda后面,不能用 r e t u r n return return返回的则不能定义在 l a m b d a lambda lambda
因为这一点, l a m b d a lambda lambda能够出现在Python语法不允许 d e f def def出现的地方:例如,在一个列表常量中或者函数调用的参数中
此外,作为一个表达式, l a m b d a lambda lambda返回了一个新的函数,可以选择性的赋值给一个变量
相反, d e f def def语句总是需要在头部将一个新的函数赋值给一个变量,而不会将这个函数作为结果返回

  • l a m b d a lambda lambda表达式内部只能包含一行代码

l a m b d a lambda lambda表达式内部只能包含一行代码,而命名函数内对此无限制
l a m b d a lambda lambda的主体简单得就好像放在 d e f def def主体的 r e t u r n return return语句中的代码一样:简单地将结果写成一个顺畅的表达式,而不是明确的返回
当然,这一切都是有预谋的——限制了程序的嵌套: l a m b d a lambda lambda为编写简单的函数而设计的,而def用来处理更大的任务

  • 自动返回结果:返回 l a m b d a lambda lambda表达式中最后一个表达式的值
  • l a m b d a lambda lambda可以直接作为Python列表或Python字典的成员
  • 嵌套问题:语句嵌套用 d e f def def,表达式嵌套用 l a m b d a lambda lambda
a = int(input())
if a > 1 :
  def result1 ():
    print('win')
else :
  def result2 ():
    print('lose')
g = lambda x : x+2
list_1 = [g(x) for x in range(10)]
print(list_1)

# [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
  • 目的不同: l a m b d a lambda lambda一般用来定义简单的函数,而 d e f def def可以定义复杂的函数
  • 不可重用: l a m b d a lambda lambda函数不能共享给别的程序调用,而 d e f def def可以。

使用 l a m b d a lambda lambda表达式的优缺点

优点

  1. 使用Py写一些执行脚本或简单的单行函数时,使用 l a m b d a lambda lambda表达式可以省去定义函数的过程,让代码更加精简
  2. 在非多次调用的函数的情况下, l a m b d a lambda lambda表达式即用即得,提高性能
  3. 对于一些抽象且不重用的函数,使用 l a m b d a lambda lambda可以避免绞尽脑汁命名的尴尬
  4. 使用 l a m b d a lambda lambda在某些时候能够让代码更容易理解

缺点

  1. 对很多Py程序员来说, l a m b d a lambda lambda表达式是一种古怪而又陌生的语法
  2. l a m b d a lambda lambda函数本身缺少名称和文档,意味着了解它们功能的唯一方式就是读代码,在某些情况下会让代码变得更加晦涩
  3. l a m b d a lambda lambda表达式只能包含一条语句,因此某些提高可读性的语言功能(如元组拆包)不能与ta们一起使用
  4. l a m b d a lambda lambda函数通常可以被替换为标准库中已存在的函数或Py内置的函数,利用已有函数是更好的选择

你可能感兴趣的:(Python,语言学习)