首页 / Python3 入门教程 / 高阶函数与函数式工具

Python3 入门教程

高阶函数与函数式工具

本教程共 70 篇 · 第 27 篇 · 更新于 2026-07-22 · 约 3 分钟阅读

PythonPython3 入门教程高阶函数map-filter-reducesortedfunctools.partial

27. 高阶函数与函数式工具

本节目标:掌握 map、filter、reduce、sorted 和 partial 的用法,能用函数式风格编写简洁代码。

什么是高阶函数

高阶函数是指接收函数作为参数,或返回函数作为结果的函数。

Python 内置了几个常用的高阶函数,配合 lambda 或自定义函数,能让代码非常紧凑。

map()

对可迭代对象的每个元素执行同一个函数:

nums = [1, 2, 3, 4, 5]

# 传统写法
squares = []
for n in nums:
    squares.append(n ** 2)

# map 写法
squares = list(map(lambda x: x ** 2, nums))
# [1, 4, 9, 16, 25]

如果有多个可迭代对象,函数接收多个参数:

a = [1, 2, 3]
b = [4, 5, 6]
result = list(map(lambda x, y: x + y, a, b))
# [5, 7, 9]
Tip

简单场景下,列表推导式 [x**2 for x in nums] 往往更易读。map 在函数已经定义好、或需要多序列并行处理时更有优势。

filter()

按条件筛选元素:

nums = [1, 2, 3, 4, 5, 6]

evens = list(filter(lambda x: x % 2 == 0, nums))
# [2, 4, 6]

# 等价推导式
[x for x in nums if x % 2 == 0]

filter 的函数返回「真值」时保留该元素。用 None 可以过滤掉所有假值:

values = [0, 1, "", "hello", [], [1, 2], None, True]
truthy = list(filter(None, values))
# [1, 'hello', [1, 2], True]

reduce()

把序列两两累积成一个值:

from functools import reduce

nums = [1, 2, 3, 4, 5]

# 累加
reduce(lambda x, y: x + y, nums)   # 15

# 累乘
reduce(lambda x, y: x * y, nums)   # 120

# 找最大值
reduce(lambda x, y: x if x > y else y, nums)   # 5

reduce 还可以指定初始值:

reduce(lambda x, y: x + y, [1, 2, 3], 100)
# 106,从 100 开始累加
Note

reduce 在 Python 3 中被移到 functools 模块。因为它往往不如显式循环好读,官方推荐谨慎使用。但某些场景(如链式运算)用它很简洁。

sorted()

排序是 Python 里最高频的操作之一。sorted() 返回新列表,不修改原数据:

nums = [3, 1, 4, 1, 5]
sorted(nums)              # [1, 1, 3, 4, 5]
sorted(nums, reverse=True) # [5, 4, 3, 1, 1]

key 参数指定排序依据:

words = ["banana", "pie", "Washington", "book"]

# 按长度排序
sorted(words, key=len)
# ['pie', 'book', 'banana', 'Washington']

# 按长度降序
sorted(words, key=len, reverse=True)

# 忽略大小写排序
sorted(words, key=str.lower)

复杂对象的排序:

students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 92},
    {"name": "Charlie", "score": 78},
]

# 按分数排序
sorted(students, key=lambda s: s["score"])

# 先按分数降序,分数相同按名字升序
sorted(students, key=lambda s: (-s["score"], s["name"]))
Tip

如果列表本身不需要保留原顺序,用列表的 .sort() 方法更快,因为它不需要创建新列表。

operator 模块

operator 模块提供了一些内置操作的函数版本,配合高阶函数用:

from operator import add, mul, itemgetter, attrgetter

reduce(add, [1, 2, 3, 4])      # 10
reduce(mul, [1, 2, 3, 4])      # 24

# itemgetter 替代 lambda 取字典/元组的字段
data = [("Alice", 25), ("Bob", 30), ("Charlie", 20)]
sorted(data, key=itemgetter(1))           # 按索引 1 排序
sorted(data, key=itemgetter(0))           # 按索引 0 排序

# attrgetter 取对象的属性
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

people = [Person("Alice", 25), Person("Bob", 30)]
sorted(people, key=attrgetter("age"))
Tip

itemgetterattrgetter 比等价的 lambda 快一点,而且写起来更短。性能敏感或代码风格统一时优先用它们。

functools.partial

partial 用来「冻结」函数的一部分参数,得到一个新函数:

from functools import partial

# 原函数
def power(base, exponent):
    return base ** exponent

# 冻结 exponent=2,得到平方函数
square = partial(power, exponent=2)
print(square(5))   # 25

# 冻结 exponent=3,得到立方函数
cube = partial(power, exponent=3)
print(cube(3))     # 27

实际应用:给 int() 指定默认进制:

from functools import partial

bin_to_int = partial(int, base=2)
print(bin_to_int("1010"))   # 10
print(bin_to_int("1111"))   # 15

函数式编程风格建议

Python 不是纯函数式语言,但适当借鉴它的思想能让代码更简洁:

  • 优先用内置高阶函数处理数据转换
  • 用 lambda 写简单的一次性函数
  • 复杂逻辑还是用 def,可读性第一
  • 不要为了追求「函数式」而写出晦涩的代码

来源:参考了 runoob「Python3 内置函数」、liaoxuefeng「函数式编程」等,改写后所得。