Python 虽说是一个面向对象的,动态语言,但是它对于函数式编程的支持其实也不错,下面是几个在函数式编程中常用的概念或内置函数。

高阶函数

高阶函数是指可以接受函数作为参数,或返回函数作为结果的函数,Python 直接支持这种语法,例如

1
2
3
4
def apply_func(func, value):
return func(value)

result = apply_func(lambda x: x * 2, 5) # 10

lambda expression

lambda 表达式(匿名函数)是用来定义没有名字的函数,通常用于快速定义短小的函数体,尤其是在传递给其他高阶函数时。 Python 支持 lambda 表达式,但是可能是由于缩进等原因,Python只允许 lambda 表达式中含有一个语句作为返回值,例如

1
2
add = lambda x, y: x + y
print(add(3, 4))

map

map 的语义是将一个函数作用于给定序列的每个元素,将作用得到的结果组成一个新序列并返回。 Python 提供了内置函数 map(),例如

1
2
3
4
5
numbers = [1, 2, 3, 4]
squared = map(lambda x: x**2, numbers) # 将每个数字平方

# 将结果转换为列表并输出
print(list(squared)) # [1, 4, 9, 16]

注意 map() 函数不是返回序列,而是返回一个一次性的迭代器,这是一个惰性求值特性,只有实际迭代时才会真正计算对应元素:

  • 如果需要直接获取所有结果,可以使用 list() 函数将其转换为列表。
  • 如果需要获取部分结果,可以逐次进行迭代。

可以通过下面的代码验证这一特点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def 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
2
3
4
5
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(lambda x: x % 2 == 0, numbers) # 过滤出其中的偶数

# 将结果转换为列表并输出
print(list(even_numbers)) # [2, 4, 6]

map() 一样,filter() 采用惰性求值的策略,返回的是一次性的迭代器,只有在实际迭代时才会计算出对应的元素。可以通过下面的代码验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def 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
2
3
4
5
from functools import reduce

numbers = [1, 2, 3, 4]
result = reduce(lambda x, y: x + y, numbers) # 求和
print(result) # 10

partial

partial 是指将一个函数的部分参数固定住,返回一个接收其它参数的新函数,通过这种方式可以创建更简洁特化的函数,避免重复传递相同参数。 Python 提供了 functools.partial() 来实现这一功能,例如

1
2
3
4
5
6
7
8
9
10
11
from functools import partial

# 定义一个函数,计算幂次
def power(base, exp):
return base ** exp

# 创建一个新的函数,将 exp 固定为 2,即平方函数
square = partial(power, exp=2)

print(square(3)) # 9
print(square(5)) # 25