itertools是Python标准库中做排列组合最轻量、最可靠的选择,不依赖第三方包,生成器实现内存友好,但必须注意它返回的是迭代器而非列表——这点踩坑最多。

直接说结论:itertools 是 Python 标准库中做排列组合最轻量、最可靠的选择,不依赖第三方包,生成器实现内存友好,但必须注意它返回的是迭代器而非列表——这点踩坑最多。
为什么 itertools.permutations() 返回空列表却没报错?
常见现象:调用 itertools.permutations([1, 2], 3) 得到空迭代器,list(...) 后是 [],不是报错。因为数学上「从 2 个元素取 3 个的排列」不存在,函数按定义合法返回空迭代器。
-
r参数大于输入可迭代对象长度时,结果恒为空,不会 raise 异常 - 想提前拦截这种逻辑错误,得自己加判断:
if r > len(iterable): raise ValueError("r cannot exceed length") - 注意:输入不能是生成器(如
range(10)可以,但(x for x in range(10))不行),否则第一次遍历后就耗尽,后续调用无输出
itertools.combinations_with_replacement() 和手写循环的区别在哪?
这个函数常被误认为只是语法糖,其实它在语义和边界处理上更严谨:允许重复选同一元素,且结果按输入顺序升序排列(即 (a, a)、(a, b)、(b, b),不会出现 (b, a))。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 参数
r可为 0,返回一个空元组()的单元素迭代器;手写循环容易漏掉该 case - 输入含重复元素(如
[1, 1, 2])时,它不自动去重——结果会包含(1, 1)、(1, 2)、(2, 2),但不会凭空多出(1, 1, 1)(除非r=3且原 list 有三个 1) - 性能上比嵌套 for 循环 + 手动去重稳定,尤其当
r较大时,避免构建中间列表
如何安全地把 itertools.product() 结果转成 NumPy 数组?
直接 np.array(list(itertools.product(...))) 在数据量大时会爆内存,因为 list() 强制展开整个迭代器。
立即学习“Python免费学习笔记(深入)”;
- 推荐分块消费:用
itertools.islice()切片 + 循环追加到预分配数组,或改用生成器表达式配合np.fromiter() -
np.fromiter(itertools.product([0,1], repeat=20), dtype=np.uint8).reshape(-1, 20)会失败——fromiter不支持嵌套 tuple 输入,必须先展平或换用np.array(list(...))(仅限小规模) - 更稳妥的做法:用
itertools.product()配合np.stack(),例如np.stack([np.array(p) for p in itertools.islice(product_iter, 10000)])
真正麻烦的不是调哪个函数,而是搞清你要的是「有序可重复」「无序不可重复」还是「带索引的笛卡尔积」——itertools 每个函数契约非常明确,但名字太像,传错参数或选错函数,结果可能完全符合语法却不符合业务逻辑。

















