目录
匿名函数
什么是匿名函数
在Python中,不通过def来声明函数名字,而是通过lambda关键字来定义的函数称为匿名函数。
lambda函数能接收任何数量(可以是0个)的参数,但只能返回一个表达式的值,lambda函数是一个函数对象,如果直接赋值给一个变量,这个变量就成了一个函数对象。
语法:lambda 参数:表达式
先写lambda关键字,然后依次写匿名函数的参数,多个参数中间用逗号连接,然后是一个冒号,冒号后面写返回的表达式。
使用lambda函数可以省去函数的定义,不需要声明一个函数然后使用,而可以在写函数的同时直接使用函数。
使用场景:
1.需要将一个函数对象作为参数来传递时,可以直接定义一个lambda函数(作为函数的参数或返回值)
2.要处理的业务符合lambda函数的情况(任意多个参数和一个返回值),并且只有一个地方会使用这个函数,不会在其他地方重用,可以使用lambda函数
3.与一些Python的内置函数配合使用,提高代码的可读性
匿名函数与普通函数的对比
def sum_func(a, b, c):
return a + b + c
sum_lambda = lambda a, b, c: a + b + c
print(sum_func(1, 100, 10000))
print(sum_lambda(1, 100, 10000))
'''
10101
10101
'''
可以看到,lambda适用于多个参数、一个返回值的情况,可以用一个变量来接收,变量是一个函数对象,执行这个函数对象的结果与执行一个普通函数的结果一样。
lambda函数比普通函数更简洁,且没有声明函数名,上面的代码是用一个变量来接收lambda函数返回的函数对象,并不是lambda函数的名字。
匿名函数的多种形式
lambda_a = lambda: 100
print(lambda_a())
# 一个参数
lambda_b = lambda num: num * 10
print(lambda_b(5))
# 多个参数
lambda_c = lambda a, b, c, d: a + b + c + d
print(lambda_c(1, 2, 3, 4))
# 表达式分支
lambda_d = lambda x: x if x % 2 == 0 else x + 1
print(lambda_d(6))
print(lambda_d(7))
'''
这是一个使用 lambda 表达式定义的函数 lambda_d,函数的功能是判断输入的参数 x 是否为偶数,如果是偶数则返回 x,否则返回 x + 1。
在你的例子中,当输入参数为 6 时,6 是偶数,因此输出结果为 6;当输入参数为 7 时,7 是奇数,因此输出结果为 8(7+1)。
'''
'''
输出:
100
50
10
6
8
'''
可以看到,lambda的参数可以0个到多个,并且返回的表达式可以是一个复杂的表达式,只要最后的值是一个值就行了。
lambda作为一个参数传递
def sub_func(a, b, func):
print('a =', a)
print('b =', b)
print('a - b =', func(a, b))
sub_func(100, 1, lambda a, b: a - b)
'''
这段代码定义了一个名为 sub_func 的函数,接受三个参数 a、b 和 func。其中,参数 func 是一个函数,
在调用 sub_func 函数时传入了一个 lambda 表达式 lambda a, b: a - b。
具体操作是将传入的参数 a 和 b 分别输出,然后通过 func 计算 a - b 的结果,并输出该结果。在这里,func 是一个 lambda 表达式,用来实现两数相减的功能。
'''
上面的代码中,sub_func中需要传入一个函数,然后这个函数在sub_func里面执行,这时候我们就可以使用lambda函数,因为lambda就是一个函数对象。
lambda函数与Python内置函数配合使用
member_list = [
{"name": "小王", "age": 99, "power": 10000},
{"name": "小李", "age": 89, "power": 9000},
{"name": "小张", "age": 120, "power": 8000}
]
new_list = sorted(member_list, key=lambda dict_: dict_["power"])
print(new_list)
number_list = [100, 77, 69, 31, 44, 56]
num_sum = list(map(lambda x: {str(x): x}, number_list))
print(num_sum)
'''
1. 对字典列表的排序:
member_list = [
{"name": "小王", "age": 99, "power": 10000},
{"name": "小李", "age": 89, "power": 9000},
{"name": "小张", "age": 120, "power": 8000}
]
new_list = sorted(member_list, key=lambda dict_: dict_["power"])
print(new_list)
这段代码首先定义了一个包含字典元素的列表 member_list,然后使用 Python 的内置函数 sorted 对该列表进行排序。通过指定 key 参数并传入 lambda 表达式,
我们可以根据字典中的 "power" 键对列表中的字典进行排序。排序后,new_list 中的字典元素将按照 "power" 的升序排列。
2. 对数字列表进行映射操作:
number_list = [100, 77, 69, 31, 44, 56]
num_sum = list(map(lambda x: {str(x): x}, number_list))
print(num_sum)
这部分代码使用了 map 函数和 lambda 表达式来将原始的数字列表映射成包含每个数字的字典列表。map 函数对 number_list 中的每个元素应用了 lambda 表达式,
并将结果收集到一个新的列表 num_sum 中。最终输出的结果是一个包含了原始数字作为键和值的字典的列表。
综上所述,第一部分对字典列表进行排序,基于字典中的 "power" 键进行升序排序;第二部分则将数字列表中的每个数字映射为包含该数字作为键和值的字典,
然后将这些字典收集到新的列表中。
'''
当使用 sorted()
函数对一个列表进行排序时,可以通过 key
参数指定一个函数来确定排序的依据。在这个例子中,key=lambda dict_: dict_["power"]
这部分代码的含义是:
lambda dict_: dict_["power"]
定义了一个匿名函数,接收一个参数dict_
,表示列表中的每个字典元素。dict_["power"]
表示在每个字典元素中取出键为 "power" 的值作为排序依据。- 因此,
key=lambda dict_: dict_["power"]
表达的含义是告诉sorted()
函数,按照每个字典元素中 "power" 键对应的值进行排序。
这样通过传入这个 lambda 函数作为 key
参数,sorted()
函数会根据每个字典元素中 "power" 键的值进行排序,从而实现了按照 "power" 键升序排序的功能。
lambda作为函数的返回值
def run_func(a, b):
return lambda c: a + b + c
return_func = run_func(1, 10000)
print(return_func)
print(return_func(100))
'''
匿名函数可以作为一个函数的返回值,在上面的代码中,run_func返回的是一个匿名函数,返回的是一个函数对象,
1. 定义函数 run_func(a, b):
- 接收两个参数 a 和 b。
- 返回一个 lambda 函数:lambda c: a + b + c。
2. 调用 run_func(1, 10000) 并将返回的 lambda 函数赋值给 return_func。
3. 打印 return_func 变量的值:
- 这里输出的内容是一个 lambda 函数的表示,类似于 <function run_func.<locals>.<lambda> at 0x00000123456789ABC>。
4. 调用 return_func(100):
- 将参数 100 传递给 return_func,实际上执行了 1 + 10000 + 100 的计算,结果为 10101。
- 打印出计算结果 10101。
因此,这段代码的作用是定义一个函数返回一个 lambda 函数,然后对返回的 lambda 函数进行调用,并输出计算结果。
'''
匿名函数可以作为一个函数的返回值,在上面的代码中,run_func返回的是一个匿名函数,返回的是一个函数对象,当我们执行这个函数时,可以得到lambda函数的结果。
注意:其中的a,b两个参数是run_func中的参数,但我们执行返回的函数return_func时,已经不在run_func的作用域内了,而lambda函数仍然能使用a,b参数。说明lambda函数会将它的运行环境保存一份,一直保留到它自己执行的时候使用。
使用匿名函数
使用匿名函数
特性
lambda 函数是匿名的:
- 所谓匿名函数,就是没有名字的函数,没有名字就代表着不必担心函数名称冲突。
lambda 函数有输入和输出:
- 匿名函数也是一个函数对象,所以可以把匿名函数赋值给一个变量,再利用变量来调用函数
- 匿名函数的输入是传入到参数列表 [list] 的值
- 匿名函数的输出是根据表达式计算得到的值
lambda 函数拥有自己的命名空间:
- 搜索变量的作用域顺序与之前的内容说的规则一致,也是 L –> E –> G –> B
以下实例说明匿名函数的以上三个特性:
a = 10
f = lambda x: x * a
print(f)
print(type(f))
print(f(3))
'''
<function <lambda> at ...> # 这里的 ... 值得是运行代码时分配的地址
<class 'function'>
30
'''
常见用法
由于 lambda
语法是固定的,其本质上只有一种用法,那就是定义一个 lambda
函数。 在实际中,根据 lambda
函数使用场景的不同,可以将 lambda
函数的用法进行简单扩展
- 将
lambda
函数赋值给一个变量,通过变量间接调用该lambda
函数。以下例子在定义加法函数后将其赋值给了变量add
,这样变量add
就指向了具有加法功能的函数。
add = lambda x, y: x + y
print(add(3, 4))
'''
7
'''
- 将
lambda
函数赋值给其他函数,从而将其他函数用该lambda
函数替换。以下例子改变了内置函数sum
的求和功能。
print(sum([1, 2, 3, 4, 5], 20))
sum = lambda *args: None
print(sum([1, 2, 3, 4, 5], 20))
'''
在这段代码中,我们首先使用了内置函数 sum,然后将其重新定义为一个 lambda 函数,然后分别对两次调用 sum 进行处理。
1. print(sum([1, 2, 3, 4, 5], 20)):
- 首先,我们调用了内置函数 sum,对列表 [1, 2, 3, 4, 5] 执行求和操作,并给定初始值 20。
- 这将计算结果为列表元素之和加上初始值,即 1 + 2 + 3 + 4 + 5 + 20,最终结果为 35。
2. sum = lambda *args: None:
- 这行代码将内置函数 sum 覆盖重新定义为了一个返回 None 的 lambda 函数,当我们后续调用 sum 时,实际上调用的是这个新定义的 lambda 函数。
3. print(sum([1, 2, 3, 4, 5], 20):
- 因为我们已经将 sum 重新定义为一个返回 None 的 lambda 函数,所以这里实际上调用的是这个 lambda 函数。
- 由于这个 lambda 函数并没有实际的求和逻辑,只是返回 None,所以这里会打印出 None。
总结:第一次调用 sum 是使用内置的求和函数计算结果为 35,而第二次调用 sum 是调用被重新定义的 lambda 函数返回 None。
'''
函数练习-8
使用 lambda 函数构造一元二次多项式
描述
一元二次多项式是最常见的一种多项式,只含一个未知数且各项最高次数为 2 的多项式称为一元二次多项式,它的标准形式为 ax2 + bx + c
请在 solution.py 里完善代码,实现 equation 函数功能。equation 函数接收三个参数 a、b 和 c 分别作为一元二次多项式标准形式的二次项、一次项和常数项。
请用 lambda 函数为 equation 函数传入一个未知数 x,并将这个 lambda 函数作为 equation 函数的返回值,求出一元二次多项式 ax2 + bx + c 的结果!
def equation(a, b, c):
return lambda x: a * x ** 2 + b * x + c
'''
当我们调用函数 equation(a, b, c) 时,会返回一个 lambda 函数,这个 lambda 函数实际上是一个闭包,它捕获了函数 equation 中的参数 a、b 和 c。
这个 lambda 函数的定义为 lambda x: a*x**2 + b*x + c,表示一个二次方程的形式:ax^2 + bx + c。
举例来说,如果我们调用 equation(2, -1, 5),将会返回一个表示二次方程 2x^2 - x + 5 的 lambda 函数。
然后我们可以使用这个 lambda 函数来计算这个二次方程在特定 x 值下的结果,比如 result = equation(2, -1, 5); print(result(3)),
就可以得到 x=3 时二次方程的计算结果。
'''