Python 教程 / 高阶函数

高阶函数

高阶函数是函数式编程的基石。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 在线代码编辑器
📝 运行结果