Python 高阶函数
高阶函数是指可以接受函数作为参数或返回函数作为结果的函数。它们增强了代码的灵活性和复用性,常见于函数式编程中。Python中的map()、filter()和lambda函数是高阶函数的典型例子。通过高阶函数,我们可以抽象通用操作,减少重复代码。
高阶函数是 Python 函数式编程的核心特性,下面我们一起来看看吧!
1. 引入高阶函数概念
前面我们说各种数据类型可以赋值给变量,其实函数也可以赋值给变量,赋值以后可以用新的变量来调用函数了。所以函数也可以作为参数传递给函数。
>>> def add(a, b):
... return a + b
...
>>> add(4, 5)
9
>>>
>>> add
<function add at 0x105083240>
>>>
>>> func = add
>>>
>>> func
<function add at 0x105083240>
>>>
>>> func(4, 5)
9
2. 如何定义高阶函数
高阶函数的定义与普通函数类似,使用def
关键字,但其参数或返回值包含函数。函数在 Python 中是一等公民,可以像变量一样传递、赋值或返回。
示例:定义接受函数作为参数的高阶函数
def apply_operation(func, x, y):
return func(x, y)
def add(a, b):
return a + b
result = apply_operation(add, 3, 5)
print(result) # 输出: 8
在这个例子中,apply_operation
是一个高阶函数,接受函数func
作为参数,并将其应用于x
和y
。
在调用 apply_operation
的时候,会将 add
函数赋值给 func
,3
赋值给 x
,5
赋值给 y
。然后在 apply_operation
内部计算完成后返回结果。
3. 使用高阶函数
高阶函数可以通过内置函数或自定义函数实现。Python 内置的高阶函数包括map()
、filter()
和reduce()
等等(在functools
模块中)。后续我们会详细介绍这些常用的内置 高阶 函数。
示例:使用map()
将函数应用于序列。
map()
函数接收2个参数,第一个参数是一个函数f、第二个参数是一个序列numbers(可以是列表、元组等等),在 map()
函数内部将 numbers 序列的每个元素都传递给 f 函数得到一组新的值序列c,然后返回c。
def f(num):
return num * num
numbers = [1, 2, 3, 4]
result = list(map(f, numbers))
print(result) # 输出: [1, 4, 9, 16]
map()
将f
函数应用于numbers
中的每个元素,返回一个map对象(需转换为列表)。
示例:使用filter()
筛选数据
def is_even(num):
return num % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
result = list(filter(is_even, numbers))
print(result) # 输出: [2, 4, 6]
filter()
使用is_even
函数筛选出numbers
中的偶数。
4. 传入函数
高阶函数的核心是能够将函数作为参数传递。这允许动态选择行为,增强代码灵活性。
示例:动态选择操作
def multiply(a, b):
return a * b
def divide(a, b):
return a / b if b != 0 else "Cannot divide by zero"
def compute(operation, x, y):
return operation(x, y)
print(compute(multiply, 4, 5)) # 输出: 20
print(compute(divide, 10, 2)) # 输出: 5.0
compute
函数接受不同的操作函数(multiply
或divide
),并根据传入的函数执行计算。
5. 使用lambda
匿名函数
lambda
函数是匿名函数(也就是没有具体的函数名),常用于高阶函数中简化代码。语法为:lambda 参数: 表达式
。
示例:结合map()
和lambda
numbers = [1, 2, 3, 4]
result = list(map(lambda x: x * x, numbers))
print(result) # 输出: [1, 4, 9, 16]
# lambda x: x * x
# 完全等效于
# def f(num):
# return num * num
lambda x: x * x
替代了定义单独的f
函数,简洁且功能相同。
6. 注意事项
- 函数纯度:高阶函数在函数式编程中应尽量保持纯函数特性(相同的输入产生相同的输出,无副作用)。
- 可读性:避免过度使用
lambda
函数,复杂的逻辑应定义为命名函数以提高可读性。 - 性能:高阶函数(如
map
和filter
)可能比列表推导式稍慢,但在某些场景下更具表达力。 - 异常处理:确保传入的函数参数正确,必要时添加类型检查或异常处理。
示例:带异常处理的高阶函数
def safe_apply(func, x, y):
try:
return func(x, y)
except Exception as e:
return f"Error: {e}"
def divide(a, b):
return a / b
print(safe_apply(divide, 10, 2)) # 输出: 5.0
print(safe_apply(divide, 10, 0)) # 输出: Error: division by zero