当前位置:首页>python>Python itertools:循环的核武器

Python itertools:循环的核武器

  • 2026-10-11 07:54:54
Python itertools:循环的核武器

同事的三层嵌套把我看懵了

上周review代码,看到同事写了个三层嵌套循环找组合。我当时就血压上来了。😂 三个for套在一起,像俄罗斯套娃,我看着都头晕。他说"这样逻辑清晰"。清晰个锤子,这是2024年了兄弟。

itertools到底是个啥

itertools是标准库里的隐藏大佬。你写循环能遇到的问题,它基本都有解。combinations、permutations、chain、groupby... 这帮人凑一块儿,就是循环界的特种部队。不用安装,开箱即用。

import itertools

# 不用写嵌套循环了,一行搞定组合
items = ['A', 'B', 'C', 'D']
for combo in itertools.combinations(items, 2):
    print(combo)
# 输出: ('A','B') ('A','C') ('A','D') ('B','C') ...

combinations 救了我的命

那天我要从20个元素里选3个做测试。要是手写循环,我得写多少行?combinations(iterable, r)直接出所有r长度的组合。重点来了——它是惰性求值的,内存根本炸不了。

from itertools import combinations

# 从100个里选3个,C(100,3) = 161700种
# 但内存不会爆炸,因为返回的是迭代器
nums = range(100)
count = 0
for triplet in combinations(nums, 3):
if sum(triplet) % 7 == 0:
        count += 1
print(f"满足条件的有 {count} 个")
# 运行飞快,内存占用稳如老狗

permutations 让我少熬一个通宵

做全排列的时候,我之前傻傻地写递归。permutations一出来,递归代码可以直接删了。每个排列都是元组形式,长度就是你要的r。注意顺序不同算不同排列,跟组合不一样。

from itertools import permutations

# 4个字母全排列,4! = 24种
chars = '甲乙丙丁'
for p in permutations(chars, 3):
    print(''.join(p))

# 带过滤条件的排列筛选
valid = [p for p in permutations(range(1,5), 4)
if p[0] * p[1] > 6]
print(f"符合条件的排列数: {len(valid)}")

groupby 差点把我整不会了

groupby这个函数有个大坑:它只对相邻相同元素分组。我第一次用没排序,结果分组碎了一地,当场懵了。必须先sort再groupby,记住了。

from itertools import groupby

# 错误用法(不排序)
data = ['A', 'B', 'A', 'A', 'B']
for k, g in groupby(data):
    print(k, list(g))
# A ['A']  B ['B']  A ['A','A']  B ['B']  ← 碎了!

# 正确用法
sorted_data = sorted(data)
for k, g in groupby(sorted_data):
    print(k, len(list(g)))
# A 2  B 2  ← 这才是我要的

无限迭代器才是真的骚

count()、cycle()、repeat()这三个无限迭代器,我第一次见的时候在想:无限循环?这不作死吗。后来做数据填充、轮询、生成无限ID的时候,真香。😂

from itertools import count, cycle, repeat, islice

# count(start=10, step=2) → 10, 12, 14, 16...
for i in islice(count(10, 2), 5):
    print(i)  # 10 12 14 16 18

# cycle 无限循环列表
colors = cycle(['红', '绿', '蓝'])
for _ in range(6):
    print(next(colors))  # 红绿蓝红绿蓝

# repeat 重复同一个值
print(list(repeat('★', 5)))  # ['★', '★', '★', '★', '★']

chain 扁平化神器

你有好几个列表想一起遍历,别用+拼接,内存浪费。chain(*iterables)直接串起来,零拷贝。我做日志合并的时候全靠它。

from itertools import chain

log1 = ['ERROR: 磁盘满', 'WARN: 内存高']
log2 = ['INFO: 启动完成']
log3 = ['ERROR: 连接超时', 'ERROR: 超时']

# 比 log1+log2+log3 省内存
for entry in chain(log1, log2, log3):
if entry.startswith('ERROR'):
        print(entry)

# chain.from_iterable 更狠,展平嵌套列表
nested = [[1,2], [3,4], [5,6]]
print(list(chain.from_iterable(nested)))
# [1, 2, 3, 4, 5, 6]

我用这几个函数搞了个笛卡尔积

product()做笛卡尔积,替代多层嵌套循环的神器。我以前写SQL生成测试数据,两层循环套了80行。用product压缩到5行。☕

from itertools import product

# 笛卡尔积:每个属性组合都覆盖到
sizes = ['S', 'M', 'L']
colors = ['黑', '白', '灰']
styles = ['圆领', 'V领']

for item in product(sizes, colors, styles):
    print(f"SKU: {'-'.join(item)}")
# 3×3×2 = 18种组合,一行搞定

最新文章

随机文章