别再写for循环了!Python自带一个神器,让100行代码缩成1行!

内容分享2小时前发布
0 17 0

有没有发现,写 Python 越久,代码越啰嗦? 本来只是想把两个列表组合一下,结果搞出一堆 for 循环、if 判断、append 操作,搞得自己都嫌弃。

你以为是自己水平不够,实则是—— 你还没用上一个“上古神器”:

itertools 模块

这玩意儿,简直就是循环界的「特种兵」。 它不张扬、不浮夸,早就藏在 Python 标准库里,却能用几行代码干掉上百行嵌套循环

今天我就带你彻底搞懂这个神器。 不废话,直接开干。

别再写for循环了!Python自带一个神器,让100行代码缩成1行!


一、先问一句:你是不是也写过这样的循环?

列如,想要生成两组数据的全部组合。

我们最朴素的写法是这样的:

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 函数是哪个? 或者,有没有遇到哪种循环场景很头疼? 留言聊聊,我们一起优化它

© 版权声明

相关文章

17 条评论

  • 头像
    鄢君宜 读者

    只会调包 有个卵用,还不如直接让AI写

    无记录
    回复
  • 头像
    花生説 投稿者

    截个图还不截全,你这到底是在炫技啊还是真别人学会点啥呀?

    无记录
    回复
  • 头像
    噗叽咕咕咕 读者

    收藏了,感谢分享

    无记录
    回复
  • 头像
    八马路 读者

    收藏学习了

    无记录
    回复
  • 头像
    Celtics-ly 读者

    和zip函数有啥差别吗

    无记录
    回复
  • 头像
    杨发哥 读者

    代码写久了就是会干这种一行干掉N行的事,为了一个月后自己还能看懂,要写N行注释解释什么是笛卡尔积。唉,还不如老老实实写for

    无记录
    回复
  • 头像
    茨木手中线 读者

    itertools是标准库还是第三方库?没有用过python很多月了。

    无记录
    回复
  • 头像
    大佬家的田不正 读者

    写代码别只看代码少就认为好,执行速度才是关键,itertools第三方库慢点要你的命!

    无记录
    回复
  • 头像
    雷公 读者

    忙半天不如我这一行:把商品按类别分组、上架时间排序,输出:名称 – 库存数量

    无记录
    回复
  • 头像
    摄影师CC-Chen 投稿者

    我还是喜欢看到循环,知道在干什么

    无记录
    回复
  • 头像
    山海不可平 读者

    100行和一行 对我的代码提交量有质的影响

    无记录
    回复
  • 头像
    银河里最闪耀的星 投稿者

    套个外壳而已

    无记录
    回复
  • 头像
    2026年3月4日提12万车 管理员

    不写for怎么for

    无记录
    回复
  • 头像
    兔吖抱紧胡萝卜_ 读者

    优雅的笛卡尔积

    无记录
    回复
  • 头像
    乱晒大龙 读者

    感觉没有R来得直观

    无记录
    回复
  • 头像
    大星吖 读者

    项目里有这么用的吗?

    无记录
    回复
  • 头像
    富迪 读者

    python修仙传

    无记录
    回复