5.7 KiB
sources, brief
| sources | brief | |
|---|---|---|
|
itertools 是 Python 中用于组合和处理迭代器的标准库工具模块。 |
itertools 模块
itertools 是 Python 标准库中用于处理 iterator 和 generator 的工具模块。它提供了一组高效、惰性求值的函数,用来实现常见的迭代模式,特别适合与 generator expression 和数据处理 pipeline 配合使用。
相关来源:summaries/04_More_generators
核心定义
itertools 的主要作用是:
- 接收一个或多个可迭代对象;
- 以迭代方式逐个处理元素;
- 返回新的迭代器;
- 避免一次性构造完整中间列表;
- 支持流式、组合式的数据处理。
因此,itertools 与 lazy evaluation 和 memory efficiency 密切相关。
在生成器体系中的位置
在 summaries/04_More_generators 中,itertools 被介绍为生成器和迭代器编程的重要辅助模块。生成器表达式可以完成简单的过滤、映射和转换,而 itertools 则提供了更多可复用的迭代模式。
例如,生成器表达式可以写出:
rows = (row for row in rows if row['name'] in names)
而 itertools 则可以进一步提供连接、重复、分组、跳过、复制等更复杂的迭代行为。
常见工具函数
文档中列出了若干 itertools 函数:
itertools.chain(s1, s2)
itertools.count(n)
itertools.cycle(s)
itertools.dropwhile(predicate, s)
itertools.groupby(s)
itertools.ifilter(predicate, s)
itertools.imap(function, s1, ... sN)
itertools.repeat(s, n)
itertools.tee(s, ncopies)
itertools.izip(s1, ... , sN)
其中一些名称如 ifilter、imap、izip 属于 Python 2 风格;在 Python 3 中,相应功能通常由内置的 filter()、map()、zip() 提供,它们本身也返回惰性迭代器。
典型迭代模式
chain:连接多个迭代对象
itertools.chain(s1, s2) 可以把多个可迭代对象串接成一个连续的迭代流。
适用场景:
- 合并多个数据源;
- 顺序处理多个文件;
- 避免创建
s1 + s2这样的中间列表。
count:生成无限计数序列
itertools.count(n) 从 n 开始持续产生数字。
它通常用于:
- 给数据流编号;
- 构造无限序列;
- 与
zip()等函数组合。
因为它是无限迭代器,所以使用时通常需要配合终止条件。
cycle:循环重复序列
itertools.cycle(s) 会不断重复遍历给定序列。
适用场景包括:
- 轮询任务;
- 周期性分配资源;
- 重复使用一组固定值。
dropwhile:按条件跳过前缀
itertools.dropwhile(predicate, s) 会在条件为真时持续跳过元素,一旦条件变为假,就开始产生后续所有元素。
这适合处理带有头部说明、注释块或预热数据的流式输入。
groupby:按相邻键分组
itertools.groupby(s) 用于把相邻元素按照某种键分组。
需要注意的是,groupby 只对相邻元素分组。如果想按全局键分组,通常需要先排序。
repeat:重复产生同一个值
itertools.repeat(s, n) 会重复产生值 s,最多 n 次。
它可以用于:
- 构造固定参数流;
- 与
map()或zip()组合; - 替代手写重复循环。
tee:复制迭代器
itertools.tee(s, ncopies) 可以把一个迭代器复制成多个独立迭代器。
这在需要多次消费同一数据流时有用。不过需要注意:如果多个副本消费进度差距很大,内部可能需要缓存未消费的数据。
设计思想
itertools 的核心思想不是“保存数据”,而是“描述迭代过程”。
这与 generator 的优势一致:
- 数据按需产生;
- 中间结果不必全部存入内存;
- 多个小工具可以组合成复杂流程;
- 迭代逻辑可以与业务处理逻辑分离。
这种思想特别适合处理:
- 大型文件;
- 日志流;
- 网络数据;
- 实时事件;
- 数据清洗管道;
- 一次性计算任务。
与生成器表达式的关系
generator expression 适合表达简单的过滤和转换,例如:
lines = (line for line in f if not line.startswith('#'))
itertools 则适合表达更通用、更可复用的迭代模式。例如,当需要连接多个流、无限计数、循环重复或分组时,使用 itertools 往往比手写生成器函数更简洁。
两者可以组合使用:
import itertools
lines = (line.strip() for line in f if not line.startswith('#'))
combined = itertools.chain(lines, other_lines)
这里生成器表达式负责过滤和清理,chain() 负责合并多个数据源。
为什么重要
itertools 重要的原因在于它把常见迭代模式标准化、工具化了。开发者不必为每个数据处理任务都手写循环或生成器函数,而是可以通过组合已有工具构建清晰的处理流程。
它体现了 summaries/04_More_generators 中强调的几个原则:
- 许多问题可以更自然地表达为迭代;
- 生成器和迭代器能提高内存效率;
- 数据处理可以构造成管道;
- 将“如何迭代”与“如何使用数据”分离,有助于代码复用。
注意事项
使用 itertools 时需要理解迭代器的一次性消费特性:
- 很多
itertools函数返回的是迭代器,不是列表; - 结果通常只能顺序消费;
- 某些迭代器可能是无限的,如
count()和cycle(); - 如果需要重复遍历,可能要重新创建迭代器,或谨慎使用
tee()。
这些特性与 lazy evaluation 一致,但也要求调用者明确掌握数据流的生命周期。
相关概念
- iterator
- generator
- generator expression
- lazy evaluation
- memory efficiency
- pipeline
- summaries/04_More_generators