有没有发现,写 Python 越久,代码越啰嗦? 本来只是想把两个列表组合一下,结果搞出一堆 for 循环、if 判断、append 操作,搞得自己都嫌弃。
你以为是自己水平不够,实则是—— 你还没用上一个“上古神器”:
itertools 模块
这玩意儿,简直就是循环界的「特种兵」。 它不张扬、不浮夸,早就藏在 Python 标准库里,却能用几行代码干掉上百行嵌套循环。
今天我就带你彻底搞懂这个神器。 不废话,直接开干。

一、先问一句:你是不是也写过这样的循环?
列如,想要生成两组数据的全部组合。
我们最朴素的写法是这样的:
colors = ['red', 'green', 'blue']
sizes = ['S', 'M', 'L']
for color in colors:
for size in sizes:
print(color, size)
没问题,结果的确 能打印出所有组合。 但问题也明显: 两层 for,看着就乱。 如果再加一个维度?三层、四层、五层……你人都没了。
而这时候,老司机只淡淡一笑,手一挥:
import itertools
for c, s in itertools.product(colors, sizes):
print(c, s)
结果一样,代码量减半,逻辑还更清晰。
product 的意思就是“笛卡尔积”, 一句话干掉两层 for,爽不爽?
二、循环不止有「嵌套」,还有「重复」
有时候我们要做的不是两组数据组合,而是对同一组数据重复排列。
列如,我们要生成所有 2 位数的密码组合:
import itertools
for p in itertools.product('ABCD', repeat=2):
print(''.join(p))
输出:
AA
AB
AC
AD
BA
...
这一行代码就能生成所有两位字母组合。 要是不用 itertools,你是不是要写成这样:
for a in 'ABCD':
for b in 'ABCD':
print(a + b)
看懂了吧? 有时候不是你不会写,是 Python 给了你更优雅的方式,你还没发现。
三、排列与组合,一行全搞定!
在数学里我们常常说排列组合,对吧? Python 也直接内置了这两个方法:permutations 和 combinations。
排列:顺序重大
import itertools
for p in itertools.permutations('ABC', 2):
print(p)
输出:
('A', 'B')
('A', 'C')
('B', 'A')
('B', 'C')
('C', 'A')
('C', 'B')
组合:顺序不重大
for c in itertools.combinations('ABC', 2):
print(c)
输出:
('A', 'B')
('A', 'C')
('B', 'C')
再也不用自己写乱七八糟的 for 嵌套了。
四、无穷序列?照样能玩!
有时候,我们需要无限生成某种模式的数据。 听起来很抽象? 举个例子:
想要循环输出数字 0, 1, 2, 0, 1, 2, … 这样无限轮回。 普通人:for + 取余,累死。 高手:itertools.cycle(),一行解决。
import itertools
for i in itertools.cycle([0, 1, 2]):
print(i)
(当然,要注意,这真的是“无限循环”,运行时要手动停止。)
还有个更有意思的——count(),它能从某个数开始往上数到无穷。
for i in itertools.count(10):
print(i)
if i > 15:
break
结果:
10
11
12
13
14
15
16
是不是有点像一个“自动生成器”? 这玩意儿在写数据流、日志编号、批量测试的时候超级有用。
五、条件切片:想停就停,想跳就跳
我们常常想要「只处理前几项」或「跳过前几项」。
列如:
import itertools
data = [1, 2, 3, 4, 5, 6]
for i in itertools.islice(data, 3):
print(i)
输出:
1
2
3
islice 就是“迭代器的切片”, 意思是“只取前 3 个,不用管后面多少”。
那如果我想跳过前 2 个再开始处理?
for i in itertools.islice(data, 2, None):
print(i)
输出:
3
4
5
6
是不是比你手动用索引更优雅? islice 特别适合处理大型流数据,列如日志、API返回、生成器结果等。
六、分组神器:groupby
有时候我们要按条件对数据进行分组。 传统写法往往又臭又长。 groupby 就是来救命的。
import itertools
data = [('A', 1), ('A', 2), ('B', 3), ('B', 4)]
for key, group in itertools.groupby(data, lambda x: x[0]):
print(key, list(group))
输出:
A [('A', 1), ('A', 2)]
B [('B', 3), ('B', 4)]
要注意的是: groupby 只会对连续一样的 key 分组, 所以如果你的数据没排序,最好先 sorted() 一下,否则分组会乱。
七、组合技:chain 连环操作
你可能有多个可迭代对象(list、tuple、range…), 想当成一个整体去遍历,怎么办?
import itertools
for x in itertools.chain([1, 2], [3, 4], [5]):
print(x)
输出:
1
2
3
4
5
这就像把几条河流汇成一条,chain 让你的遍历逻辑瞬间丝滑。
八、过滤神器:compress
你可能想根据某些条件过滤列表里的数据。 当然,你可以写 for + if, 但用 compress 更优雅。
import itertools
data = ['a', 'b', 'c', 'd']
selectors = [1, 0, 1, 0]
for i in itertools.compress(data, selectors):
print(i)
输出:
a
c
selectors 就像一个「开关列表」,1 表明保留,0 表明丢弃。 这比 list comprehension 更直观。
九、实战场景:组合参数自动生成
假设你在写一个测试脚本,需要对参数组合跑不同用例:
import itertools
colors = ['red', 'green']
sizes = ['S', 'M']
styles = ['casual', 'formal']
for c, s, st in itertools.product(colors, sizes, styles):
print(c, s, st)
直接生成所有组合,一行搞定,想跑多少测试都可以自动生成。 这在写自动化测试、机器学习参数调优时都超级实用。
十、最后的提议
itertools 这玩意儿, 你刚接触时可能觉得“不就是循环优化嘛”, 但真用熟了,你会发现—— 它不是工具,是思维方式。
从手写循环,到用迭代器思维去处理数据, 你的代码不只是“更短”, 而是更「优雅、可复用、像流水一样流畅」。
✅总结一下:
|
功能 |
方法 |
说明 |
|
笛卡尔积 |
product() |
多重循环合并 |
|
排列组合 |
permutations(), combinations() |
数学意义下的组合生成 |
|
无限序列 |
count(), cycle() |
自动生成或循环数据 |
|
切片 |
islice() |
控制数据截取范围 |
|
分组 |
groupby() |
按条件分组连续元素 |
|
链接 |
chain() |
多个可迭代对象拼接 |
|
过滤 |
compress() |
按条件筛选数据 |
最后我想说—— 真正的 Python 高手,不是写出最多的代码, 而是用最少的代码,做最多的事。
别再盯着 for 循环了,学会 itertools,你就能让循环为你跳舞。
你平时最常用的 itertools 函数是哪个? 或者,有没有遇到哪种循环场景很头疼? 留言聊聊,我们一起优化它

只会调包 有个卵用,还不如直接让AI写
截个图还不截全,你这到底是在炫技啊还是真别人学会点啥呀?
收藏了,感谢分享
收藏学习了
和zip函数有啥差别吗
代码写久了就是会干这种一行干掉N行的事,为了一个月后自己还能看懂,要写N行注释解释什么是笛卡尔积。唉,还不如老老实实写for
itertools是标准库还是第三方库?没有用过python很多月了。
写代码别只看代码少就认为好,执行速度才是关键,itertools第三方库慢点要你的命!
忙半天不如我这一行:把商品按类别分组、上架时间排序,输出:名称 – 库存数量
我还是喜欢看到循环,知道在干什么
100行和一行 对我的代码提交量有质的影响
套个外壳而已
不写for怎么for
优雅的笛卡尔积
感觉没有R来得直观
项目里有这么用的吗?
python修仙传