Python 学习笔记——12.函数式编程
Python 虽说是一个面向对象的,动态语言,但是它对于函数式编程的支持其实也不错,下面是几个在函数式编程中常用的概念或内置函数。
高阶函数
高阶函数是指可以接受函数作为参数,或返回函数作为结果的函数,Python
直接支持这种语法,例如 1
2
3
4def apply_func(func, value):
return func(value)
result = apply_func(lambda x: x * 2, 5) # 10
lambda expression
lambda 表达式(匿名函数)是用来定义没有名字的函数,通常用于快速定义短小的函数体,尤其是在传递给其他高阶函数时。 Python 支持 lambda 表达式,但是可能是由于缩进等原因,Python只允许 lambda 表达式中含有一个语句作为返回值,例如
1 | add = lambda x, y: x + y |
map
map
的语义是将一个函数作用于给定序列的每个元素,将作用得到的结果组成一个新序列并返回。
Python 提供了内置函数 map()
,例如
1 | numbers = [1, 2, 3, 4] |
注意 map()
函数不是返回序列,而是返回一个一次性的迭代器,这是一个惰性求值特性,只有实际迭代时才会真正计算对应元素:
- 如果需要直接获取所有结果,可以使用
list()
函数将其转换为列表。 - 如果需要获取部分结果,可以逐次进行迭代。
可以通过下面的代码验证这一特点 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21def print_and_square(x):
print(f"square {x}")
return x**2
numbers = [1, 2, 3, 4]
mapped = map(print_and_square, numbers) # no output
print("starting...")
for val in mapped:
print(f"mapped value: {val}")
# starting...
# square 1
# mapped value: 1
# square 2
# mapped value: 4
# square 3
# mapped value: 9
# square 4
# mapped value: 16
在编程的语境中,
map
实际上有两种语义:一种是用于映射操作,另一种是更常见的字典数据结构。 在 Python 中,dict
用来表示字典,而map
用于映射操作。然而,在 C++ 中,map
早就被用来表示字典,因此在进行映射操作时,C++ 选择了transform
来代替map
。
filter
filter
是指根据给定的条件从序列中过滤元素,将满足要求的元素组成一个新序列并返回。
Python 提供了内置函数 filter()
,例如
1 | numbers = [1, 2, 3, 4, 5, 6] |
和 map()
一样,filter()
采用惰性求值的策略,返回的是一次性的迭代器,只有在实际迭代时才会计算出对应的元素。可以通过下面的代码验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def print_and_check_even(x):
print(f"check {x}")
return x % 2 == 0
numbers = [1, 2, 3, 4]
filtered = filter(print_and_check_even, numbers) # no output
print("starting...")
for val in filtered:
print(f"filtered value: {val}")
# starting...
# check 1
# check 2
# filtered value: 2
# check 3
# check 4
# filtered value: 4
reduce
reduce
是指将一个函数应用于序列的前两个元素,然后将结果与序列中的下一个元素继续进行操作,直到处理完所有元素,最终返回一个单一结果。
应用情景包括对数据进行累积或聚合的操作,如求和、求积、连接字符串等。
Python 提供了 functools.reduce()
来实现这一功能,例如
1 | from functools import reduce |
partial
partial
是指将一个函数的部分参数固定住,返回一个接收其它参数的新函数,通过这种方式可以创建更简洁特化的函数,避免重复传递相同参数。
Python 提供了 functools.partial()
来实现这一功能,例如
1 | from functools import partial |