CodeWalk

itertools高级迭代器:cycle/count/accumulate/islice/tee

作者:屠龙少年 · 2026-05-30 12:55

请详细介绍Python itertools模块中以下高阶函数的原理和使用场景:itertools.cycleitertools.countitertools.accumulateitertools.isliceitertools.teeitertools.zip_longestitertools.pairwise。给出一个用itertools实现的滑动窗口平均值函数,以及用tee实现双向迭代的示例。处理无限迭代器时有哪些注意事项?

回答

屠龙少年

高级itertools函数

import itertools

# cycle:无限重复
cycled = itertools.cycle(['A', 'B', 'C'])
[next(cycled) for _ in range(5)]  # ['A','B','C','A','B']

# count:无限计数
itertools.count(start=10, step=2)  # 10, 12, 14, ...

# accumulate:累加(可自定义函数)
itertools.accumulate([1, 2, 3, 4, 5])  # 1, 3, 6, 10, 15
itertools.accumulate([1, 2, 3, 4], max)  # 1, 2, 3, 4(累计最大值)

# islice:切片迭代器(惰性)
itertools.islice(range(1000000), 10, 20)  # 只生成10-19,不计算前面的

# tee:复制迭代器为多个(内存消耗随差异增大)
ite1, ite2 = itertools.tee([1,2,3,4,5], 2)
list(ite1)  # [1,2,3,4,5]
list(ite2)  # [1,2,3,4,5]

# zip_longest:短序列补默认值
itertools.zip_longest([1,2], [10,20,30], fillvalue=0)  # (1,10),(2,20),(0,30)

# pairwise:连续配对(Python 3.10+)
itertools.pairwise([1,2,3,4])  # (1,2),(2,3),(3,4)

滑动窗口平均值

def moving_average(iterable, n):
    it = iter(iterable)
    window = list(itertools.islice(it, n))
    if len(window) == n:
        yield sum(window) / n
    for elem in it:
        window.pop(0)
        window.append(elem)
        yield sum(window) / n

无限迭代器注意事项

  • 必须设退出条件(itertools.islicebreak
  • tee会缓存已消耗的元素,如果两个迭代器差异很大,内存消耗大
  • cycle是无限循环,不要在list()中直接使用
  • accumulateinitial参数(3.8+)可设置初始值