为何itertools的combinations仅能使用一次?如何复用?
itertools.combinations 对象只能遍历一次的原因及复用方法
问题现象
使用itertools.combinations时,生成的对象仅能被遍历一次,后续遍历会得到空结果:
from itertools import combinations comb = combinations(range(0, 5), 2) xyLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb] # 输出:[('PCA0', 'PCA1'), ('PCA0', 'PCA2'), ..., ('PCA3', 'PCA4')]
但第二次遍历同一个对象时,结果为空:
comb = combinations(range(0, 5), 2) xyLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb] yxLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb] print(yxLabels) # 输出:[]
原因
itertools.combinations返回的是迭代器(iterator),迭代器的核心特性是惰性生成元素:遍历过程中才逐个计算并返回元素,遍历结束后,迭代器内部的指针会移动到末尾,没有剩余元素可以再生成,因此后续遍历不会得到任何结果。
仅创建一次实现多次使用的方法
1. 转换为列表存储
将迭代器一次性转换为列表,列表是可重复遍历的容器,适合数据量不大的场景:
from itertools import combinations # 一次性生成所有组合并存入列表 comb_list = list(combinations(range(0, 5), 2)) # 可以多次遍历列表 xyLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb_list] yxLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb_list] print(yxLabels) # 正常输出所有组合
2. 用生成器函数封装逻辑
如果数据量较大,不想一次性占用内存,可以写一个生成器函数,每次调用都会返回新的combinations迭代器:
from itertools import combinations def generate_combinations(): return combinations(range(0, 5), 2) # 每次调用函数得到新的迭代器,实现复用逻辑 xyLabels = [(f'PCA{x}', f'PCA{y}') for x, y in generate_combinations()] yxLabels = [(f'PCA{x}', f'PCA{y}') for x, y in generate_combinations()]
3. 使用itertools.tee复制迭代器
itertools.tee可以复制出多个独立的迭代器,适合需要同时多次遍历原迭代器的场景(注意要在原迭代器未开始遍历前复制):
from itertools import combinations, tee comb = combinations(range(0, 5), 2) # 复制出两个独立的迭代器 comb1, comb2 = tee(comb) # 分别遍历两个迭代器 xyLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb1] yxLabels = [(f'PCA{x}', f'PCA{y}') for x, y in comb2]
内容的提问来源于stack exchange,提问作者tesla john
相关产品推荐
相关产品推荐

