第 30 课 · 进阶 · 20 分钟

Python itertools

组合惰性迭代器,完成计数、拼接和分组。

itertoolscountchaingroupby

早高峰的订单像一条长河,后厨却按十份一批做。itertools 可以切片,又不用复制整条河。哪个工具分组时不会丢掉余数?

itertools 为迭代器流水线提供小型积木。除非你主动要求,它们不会创建完整列表,因此很适合与生成器组合。先掌握 count、islice、chain 和 groupby,再用它们组合,而不是再写一个索引循环。 你还会累积总量、用 tee 复制迭代器,并构造组合。

不用 range 也能计数

count 会产生无限序列。配合 islice 只请求固定数量的值。islice 适用于任何可迭代对象,不只是列表,而且返回迭代器。

from itertools import count, islice
print(list(islice(count(10), 3)))

给无限序列加上边界

用 chain 拼接可迭代对象

chain 会依次读取一个可迭代对象,再读取下一个,不构建中间列表。数据来自不同来源时很方便。只有需要打印或重复使用时,才用 list 包起来。

from itertools import chain
print(list(chain([1, 2], ["a", "b"])))

把多段合成一个流

分组相邻的值

groupby 会把键相同的连续元素分到一组。它不会替你排序,所以相同键分散在各处时要先排序。分组结果是迭代器,必须在前进到下一个键之前消费完。

from itertools import groupby
data = [("a", 1), ("a", 2), ("b", 3)]
for key, group in groupby(data, key=lambda pair: pair[0]):
    print(key, list(group))

相同键的连续片段

accumulate 与 pairwise 派生流

accumulate 把值变成运行总量;pairwise 产出相邻对。两者都是惰性的,不用索引循环就能表达关系。累加器需要零这样的起点时,用 initial=。

from itertools import accumulate, pairwise
values = [4, 3, 2]
print(list(accumulate(values)))
print(list(pairwise(values)))
print(list(accumulate(values, initial=0)))

运行总量与相邻对

tee 复制迭代器,但会缓冲

tee 在一个源上返回两个独立迭代器。它不是深拷贝:一个分支提前取走的值会为另一个分支缓冲。两个分支都要消费;数据小到可以直接存下时,优先用列表。

from itertools import tee
values = iter([1, 2, 3])
a, b = tee(values)
print(list(a))
print(list(b))
print(list(a))

两个读者,一个带缓冲的源

组合与笛卡尔积

combinations 选出不重复、无序的组合;product 构造输入之间的所有配对。结果数量增长很快,所以输入要小。它们适合测试矩阵和小型搜索空间,不适合暴力枚举大数据。

from itertools import combinations, product
print(list(combinations(["a", "b", "c"], 2)))
print(list(product([1, 2], ["x", "y"])))

小型组合积木

本课要点

  • count 可以表示无限的等差序列。
  • islice 可以从任何可迭代对象中截取有限前缀。
  • chain 会把多个可迭代对象首尾相接。
  • groupby 分组相邻元素;键分散时要先排序。
  • itertools 函数返回迭代器,不是列表。
  • accumulate 和 pairwise 派生惰性流;tee 会缓冲;组合数量增长很快。

常见错误

  • 直接对 itertools 返回的迭代器做下标访问。
  • 在前进 groupby 之前忘记消费当前分组。
  • 对未排序数据使用 groupby,却期待全局分组。
  • 对超大流使用 tee,却以为它完全不占内存。
轮到你

打印 count(10) 的前三个值,再用 chain 拼接 [1, 2] 和 [3]。

动手试试

改改变量、先预测输出,再运行代码。第一次点击“运行代码”时会下载 Python 运行时,可能需要几秒钟。

浏览器内 Python本地运行 · 无需账号
首次运行会从 CDN 下载 Pyodide。修改后点击“运行代码”。

练习本课

12 道题,作答后立即看到解释。

查看 12 道题答案开始练习
← dataclassescollections →