高阶函数
高阶函数是函数式编程的基石。Python内置了多个高阶函数,如map()、filter()、reduce(),让我们能用更优雅的方式处理数据。
什么是高阶函数?
高阶函数是指满足以下任一条件的函数:
- 接收一个或多个函数作为参数
- 返回一个函数作为结果
┌─────────────────────────────────────────────────────────────────────┐ │ 高阶函数示意图 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 普通函数: 高阶函数: │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ f(x) = x² │ │ g(func, x) │ │ │ │ │ │ │ │ │ │ │ 输入 x │ │ ┌──┴──┐ │ │ │ │ │ │ │ │ │ │ │ │ │ 输出 x² │ │ func x │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ Python 内置高阶函数: │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ map(func, iterable) - 对每个元素应用函数 │ │ │ │ filter(func, iterable) - 过滤满足条件的元素 │ │ │ │ reduce(func, iterable) - 累积计算 │ │ │ │ sorted(iterable, key) - 排序(key是函数) │ │ │ │ max(iterable, key) - 最大值(key是函数) │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
# 高阶函数示例: 接收函数作为参数
def apply_twice(func, x):
return func(func(x))
def double(x):
return x * 2
def square(x):
return x ** 2
print(apply_twice(double, 5)) # 20 (5*2*2)
print(apply_twice(square, 3)) # 81 (3²²)
# 高阶函数示例: 返回函数
def make_power(exp):
def power(base):
return base ** exp
return power
square = make_power(2)
cube = make_power(3)
print(square(5)) # 25
print(cube(5)) # 125
map() 函数
map(func, iterable) 对序列中的每个元素应用函数,返回迭代器。
┌─────────────────────────────────────────────────────────────────────┐ │ map() 执行流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ map(lambda x: x**2, [1, 2, 3, 4, 5]) │ │ │ │ 输入序列: [1, 2, 3, 4, 5] │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ lambda x**2: [1², 2², 3², 4², 5²] │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ 输出序列: [1, 4, 9, 16, 25] │ │ │ │ 关键点: 返回的是迭代器,惰性计算 │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
# 基本用法
numbers = [1, 2, 3, 4, 5]
# 使用 lambda
squares = map(lambda x: x ** 2, numbers)
print(list(squares))
# [1, 4, 9, 16, 25]
# 使用普通函数
def to_upper(s):
return s.upper()
words = ["hello", "world"]
upper_words = map(to_upper, words)
print(list(upper_words))
# ['HELLO', 'WORLD']
# 转换数据类型
str_nums = ["1", "2", "3"]
ints = map(int, str_nums)
print(list(ints))
# [1, 2, 3]
filter() 函数
filter(func, iterable) 过滤序列,返回满足条件的元素。
┌─────────────────────────────────────────────────────────────────────┐ │ filter() 执行流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ filter(lambda x: x%2==0, [1, 2, 3, 4, 5, 6]) │ │ │ │ 输入序列: [1, 2, 3, 4, 5, 6] │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ▼ │ │ lambda: [F, T, F, T, F, T] │ │ 1%2 2%2 3%2 4%2 5%2 6%2 │ │ =1 =0 =1 =0 =1 =0 │ │ │ │ │ │ │ │ │ │ ▼ │ ▼ │ ▼ │ │ │ 输出序列: [2, 4, 6] │ │ │ └───────────┴───────────┘ │ │ 保留 T (True) 的元素 │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
# 基本用法 - 过滤偶数
numbers = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens))
# [2, 4, 6]
# 过滤长度大于3的字符串
words = ["hi", "hello", "hey", "world", "go"]
long_words = filter(lambda w: len(w) > 3, words)
print(list(long_words))
# ['hello', 'world']
# 过滤空值
values = [0, 1, "", "hello", None, False, 42]
non_empty = filter(None, values) # None 表示只保留真值
print(list(non_empty))
# [1, 'hello', 42]
reduce() 函数
reduce(func, iterable, initializer) 对序列进行累积计算。需要从 functools 导入。
┌─────────────────────────────────────────────────────────────────────┐ │ reduce() 执行流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) │ │ │ │ 步骤 1: x=1, y=2 ──▶ 1+2 = 3 │ │ 步骤 2: x=3, y=3 ──▶ 3+3 = 6 │ │ 步骤 3: x=6, y=4 ──▶ 6+4 = 10 │ │ 步骤 4: x=10, y=5 ──▶ 10+5 = 15 │ │ │ │ 结果: 15 │ │ │ │ 图形化: │ │ │ │ [1, 2, 3, 4, 5] │ │ │ │ │ │ └───┼──────────────────────┐ │ │ ▼ ▼ │ │ [3] │ │ │ │ │ │ │ └──────────┬───────────┘ │ │ ▼ │ │ [6] │ │ │ │ │ └────────────┬───────────┘ │ │ ▼ │ │ [10] │ │ │ │ │ └────────────┐ │ │ ▼ │ │ [15] │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
from functools import reduce
# 求和
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
print(f"求和: {total}")
# 15
# 求乘积
product = reduce(lambda x, y: x * y, numbers, 1) # 初始值 1
print(f"求积: {product}")
# 120
# 找最大值
max_val = reduce(lambda a, b: a if a > b else b, numbers)
print(f"最大值: {max_val}")
# 5
# 字符串连接
words = ["Hello", " ", "World", "!"]
sentence = reduce(lambda a, b: a + b, words)
print(sentence)
# "Hello World!"
zip() 函数
zip(*iterables) 将多个序列组合成元组序列。
┌─────────────────────────────────────────────────────────────────────┐ │ zip() 执行流程 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ zip([1,2,3], ['a','b','c']) │ │ │ │ [1, 2, 3] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ (1, 'a') │ │ │ │ │ [1, 2, 3] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ (2, 'b') │ │ │ │ │ [1, 2, 3] │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ (3, 'c') │ │ │ │ 结果: [[(1,'a'), (2,'b'), (3,'c')] │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
# 基本用法
names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]
# 组合成元组
combined = zip(names, scores)
print(list(combined))
# [[('Alice', 95), ('Bob', 87), ('Charlie', 92)]
# 创建字典
score_dict = dict(zip(names, scores))
print(score_dict)
# {'Alice': 95, 'Bob': 87, 'Charlie': 92}
# 处理不同长度的序列
short = [1, 2]
long = ['a', 'b', 'c', 'd']
result = zip(short, long) # 以最短的为准
print(list(result))
# [[(1, 'a'), (2, 'b')]
enumerate() 函数
enumerate(iterable, start=0) 为序列添加索引。
Python
# 基本用法
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 0: apple
# 1: banana
# 2: cherry
# 从1开始编号
for i, fruit in enumerate(fruits, start=1):
print(f"{i}. {fruit}")
# 1. apple
# 2. banana
# 3. cherry
# 创建字典(带索引)
indexed = {i: fruit for i, fruit enumerate(fruits)}
print(indexed)
# {0: 'apple', 1: 'banana', 2: 'cherry'}
sorted() 和 sort()
sorted(iterable, key, reverse) 返回排序后的新列表,list.sort() 原地排序。
Python
# 基本排序
numbers = [5, 2, 8, 1, 9]
sorted_nums = sorted(numbers)
print(sorted_nums)
# [1, 2, 5, 8, 9]
# 降序排列
descending = sorted(numbers, reverse=True)
print(descending)
# [9, 8, 5, 2, 1]
# 按绝对值排序
mixed = [-3, 1, -5, 2, -1]
by_abs = sorted(mixed, key=abs)
print(by_abs)
# [1, -1, 2, -3, -5]
# 按字符串长度排序
words = ["apple", "hi", "banana"]
by_len = sorted(words, key=len)
print(by_len)
# ['hi', 'apple', 'banana']
# 原列表排序 (sort)
nums = [5, 2, 8]
nums.sort()
print(nums)
# [2, 5, 8]
高阶函数组合
高阶函数可以组合使用,实现复杂的数据处理流水线。
┌─────────────────────────────────────────────────────────────────────┐ │ 函数组合流水线 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 数据: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] │ │ │ │ 目标: 计算偶数的平方和 │ │ │ │ 流水线: │ │ │ │ [1,2,3,4,5,6,7,8,9,10] │ │ │ │ │ ▼ filter (x % 2 == 0) │ │ [2,4,6,8,10] │ │ │ │ │ ▼ map (x ** 2) │ │ [4,16,36,64,100] │ │ │ │ │ ▼ reduce (x + y) │ │ 220 │ │ │ └─────────────────────────────────────────────────────────────────────┘
Python
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 计算偶数的平方和
result = reduce(
lambda x, y: x + y,
map(
lambda x: x ** 2,
filter(lambda x: x % 2 == 0, numbers)
)
)
print(f"偶数的平方和: {result}")
# 220
# 等价的列表推导式 (更易读)
result2 = sum([x**2 for x in numbers if x % 2 == 0])
print(f"偶数的平方和: {result2}")
# 220
高阶函数 vs 列表推导式
- 列表推导式:更直观,适合简单操作
- 高阶函数:适合复杂的多步骤处理流水线
- 实际使用中,根据可读性选择
章节测验
问题1: map() 函数返回的是什么类型?
问题2: filter(lambda x: x>3, [1,2,3,4,5]) 的结果是?
问题3: reduce 需要从哪里导入?
问题4: zip([1,2], ['a','b','c']) 的结果长度是?
练习题
练习1: 数据转换
将一组温度从摄氏度转换为华氏度。
F = C * 9/5 + 32
输入: [0, 100, 37]
输出: [32.0, 212.0, 98.6]
练习2: 复杂过滤
从列表中过滤出既是偶数又大于10的数。
输入: [5, 10, 12, 8, 15, 20, 7]
输出: [12, 20]
练习3: 组合操作
计算字符串列表中每个单词的长度。
输入: ["apple", "banana", "cherry"]
输出: [5, 6, 6]
🐍 Python 在线代码编辑器
📝 运行结果