脚本专家 发表于 2026-7-20 09:00:01

Python itertools模块常用方法详解与数据处理实战

Python 标准库中的 itertools 模块是处理迭代器的宝藏工具,其核心函数采用惰性求值机制,不一次性加载全部数据,处理超大文件时内存占用极低,且底层用 C 实现,速度远超手写循环。理解 itertools 之前需要区分可迭代对象(Iterable)和迭代器(Iterator):前者能被 for 循环遍历,后者只能调用 next() 向前获取元素,所有 itertools 函数返回的都是迭代器。

一、最常用的函数:日常代码的主力军

chain() 与 chain.from_iterable()
chain() 将多个可迭代对象首尾拼接成一个迭代器,不生成新列表。例如:

from itertools import chain
result = list(chain(, , ))
# 输出

chain.from_iterable() 用于展平嵌套列表,避免手动解包:

nested = [, , ]
result = list(chain.from_iterable(nested))
# 输出

实际场景:合并爬虫采集的多个页面数据,比 sum(lists, []) 更高效。

islice() — 迭代器切片
对迭代器执行类似列表的切片操作,但不支持负索引。

from itertools import count, islice
# 从无限计数器中取前5个
first_five = list(islice(count(10), 5))
# 输出
# 读取大文件的第4到10行,无需载入全部
with open("bigfile.txt") as f:
    lines = list(islice(f, 3, 10))


groupby() — 分组(注意预排序)
按照键将连续相同元素分组,类似 Unix 的 uniq 命令。重要:必须先按分组键排序,否则结果异常。

from itertools import groupby
data = [
    {"name": "Alice", "dept": "Engineering"},
    {"name": "Bob", "dept": "Engineering"},
    {"name": "Carol", "dept": "Marketing"},
]
data.sort(key=lambda x: x["dept"])
for dept, members in groupby(data, key=lambda x: x["dept"]):
    print(dept, list(members))


accumulate() — 累积计算
默认做累加,但可接受任意二元函数,实现累积乘积、滚动最大值等。

from itertools import accumulate
import operator
nums =
# 累加:1 3 6 10 15
print(list(accumulate(nums)))
# 累积乘积:1 2 6 24 120
print(list(accumulate(nums, operator.mul)))
# 带初始值
print(list(accumulate(nums, initial=100)))
# 输出


pairwise() 与 batched() — 相邻配对与批量分组
pairwise(Python 3.10+)生成相邻元素配对,便于计算差值:

from itertools import pairwise
prices =
changes =
# 输出

batched(Python 3.12+)将迭代器按固定大小分批,替代手写切片循环:

from itertools import batched
data = range(10)
for batch in batched(data, 3):
    print(batch)
# 输出 (0,1,2) (3,4,5) (6,7,8) (9,)


二、进阶函数:用得少但关键时刻救命

starmap() — 解包参数映射
当函数需要接收元组参数时,比 map() 更简洁:

from itertools import starmap
pairs = [(2, 5), (3, 2), (10, 3)]
result = list(starmap(pow, pairs))
# 输出


tee() — 复制迭代器(注意内存)
将迭代器复制为 n 个独立副本,但内部会缓存进度差,造成内存消耗。使用后原迭代器不应再使用。

from itertools import tee
a, b = tee()
print(list(a))#
print(list(b))#


zip_longest() — 补齐的 zip
以最长序列为准,短序列用 fillvalue 填充,避免丢失数据:

from itertools import zip_longest
a =
b = ['x', 'y']
result = list(zip_longest(a, b, fillvalue='-'))
# 输出 [(1,'x'), (2,'y'), (3,'-'), (4,'-')]


takewhile() 与 dropwhile() — 条件截断
takewhile 从开头取满足条件的元素,遇到第一个不满足即停止;dropwhile 跳过开头满足条件的元素,然后输出剩余全部(不再判断)。

from itertools import takewhile, dropwhile
data =
list(takewhile(lambda x: x < 5, data))#
list(dropwhile(lambda x: x < 5, data))#


三、无限迭代器:谨慎使用,必须配合截断
count(start, step) 无限计数;cycle 无限循环序列;repeat 重复对象。使用时需配合 islice、takewhile 或 zip 截断,否则死循环。

from itertools import count, cycle, repeat
# count 配合 zip 实现自定义起始行号
for i, item in zip(count(1001), ["apple", "banana"]):
    print(i, item)
# 输出 (1001, 'apple') (1002, 'banana')

# repeat 重复固定次数
list(repeat(7, 3))#

注意:cycle 会复制整个序列到内存,处理大序列时需谨慎。

四、组合迭代器:排列组合的数学工具
combinations(组合,顺序无关不重复)、permutations(排列,顺序有关不重复)、product(笛卡尔积)、combinations_with_replacement(允许重复的组合)。

from itertools import combinations, permutations, product, combinations_with_replacement
items = ['A', 'B', 'C']
# 组合:C(3,2)=3
list(combinations(items, 2))# [('A','B'),('A','C'),('B','C')]
# 排列:P(3,2)=6
list(permutations(items, 2))# [('A','B'),('A','C'),('B','A'),('B','C'),('C','A'),('C','B')]
# 笛卡尔积
list(product(, repeat=3))# 8个二进制
# 有放回组合
list(combinations_with_replacement('AB', 2))# [('A','A'),('A','B'),('B','B')]


五、实战:组合使用才是威力
单个函数是积木,组合可搭建高效数据处理流水线。
场景:分页 API 跳过前两页取后三页并展平

from itertools import chain, islice
def fetch_page(n):
    return
pages = (fetch_page(n) for n in range(10))
result = list(chain.from_iterable(islice(pages, 2, 5)))
# 输出

场景:找出列表中连续递增的片段

from itertools import groupby, pairwise
nums =
diffs =
# 将连续 +1 的差值分组
result = []
for k, g in groupby(enumerate(diffs), lambda x: x):
    if k == 1:
      indices =
      result.append((indices, indices[-1]+2))
# 结果表示从第0到第2、第4到第6为连续递增片段


六、注意事项
1. 迭代器只能遍历一次,需要多次使用请转为列表或使用 tee()。
2. groupby 必须预排序,否则分组异常。
3. 无限迭代器必须配合截断函数(islice、takewhile 等)使用,避免死循环。
4. cycle 内部会复制整个序列,内存敏感时需注意。
5. islice 不支持负索引,取最后 N 个元素可用 collections.deque(iterable, maxlen=N)。

掌握 itertools 的关键不是背参数,而是写代码时自然想到用 accumulate、chain.from_iterable 等替代手写循环,写出既优雅又高效的 Python 代码。

热心网友6 发表于 2026-7-20 09:10:00

Re: Python itertools模块常用方法详解与数据处理实战

非常感谢楼主的详细整理!刚好最近在处理一些大数据流,itertools 的惰性求值确实帮了大忙。你提到的 groupby 预排序强调得很到位,我一开始没注意踩过坑,后来才发现必须先 sort。另外 tee 的内存开销也提醒得很及时,以前总以为复制迭代器没代价。建议新手可以多练习 combine 一下 chain 和 islice,处理超大文件特别顺手。期待你后续的无限迭代器部分!

热心网友6 发表于 2026-7-20 09:10:00

Re: Python itertools模块常用方法详解与数据处理实战

楼主写得太详细了,把 itertools 的核心用法和内存优势都讲透了,尤其是 groupby 必须预排序这个坑,刚接触时很容易忽略。chain.from_iterable 展平嵌套列表确实比列表推导省心,而 pairwise 配合 accumulate 做差分和累积运算在数据处理里简直神器。想请教一下,实际工作中处理几十 GB 的日志文件时,用 islice 按行切片读取和直接用 enumerate 跳出循环相比,性能差异明显吗?还有 batched 在 3.12 才引入,低版本 Python 下有没有你能推荐的替代写法?

热心网友3 发表于 2026-7-20 09:15:00

Re: Python itertools模块常用方法详解与数据处理实战

非常感谢楼主这么详尽的分享!平时写脚本时经常用到`chain.from_iterable`展平数据,还有`islice`处理大文件确实比手动切片省内存。之前用`groupby`没注意预排序,踩过坑,楼主特意强调了这点很实用。另外`pairwise`和`batched`在新版本里真的太方便了,之前都是自己写循环分段。收藏了,以后写代码前先翻翻这个贴。
页: [1]
查看完整版本: Python itertools模块常用方法详解与数据处理实战