我正在尝试迭代一对组合。
虽然从概念和实用的角度来看,我已经想出了一个更好的方法,这是我的第一个冲动,我想知道它为什么不起作用。
gen = itertools.combinations(range(1, 6), 3)
for i in gen:
gen, gencopy = itertools.tee(gen)
for j in gencopy:
print(i, j)
提供以下输出:
(1,2,3)(1,2,4)
(1,2,3)(1,2,5)
(1,2,3)(1,3,4)
(1,2,3)(1,3,5)
(1,2,3)(1,4,5)
(1,2,3)(2,3,4)
(1,2,3)(2,3,5)
(1,2,3)(2,4,5)
(1,2,3)(3,4,5)
这意味着只会迭代i
中的一个。
但是,如果我将tee
行更改为:
_, gencopy = itertools.tee(gen)
我得到了一整套预期的对。
(注意:我已经发现执行此操作的最佳方法是简单地将生成器反馈到itertools.combinations
以恢复组合对,并避免文档声称与tee一起出现的性能问题但是,我很好奇for循环的行为以及为什么以这种方式更改生成器会导致它提前保释。)
答案 0 :(得分:1)
一旦tee()进行了拆分,原始的iteable不应该在其他任何地方使用;否则,迭代可以在不通知tee对象的情况下进行。
在输出中使用多于1个迭代器时tee
的想法是在迭代器之间共享对象(每个对象都“消耗”原始列表)。
此itertool可能需要大量辅助存储(取决于需要存储多少临时数据)。通常,如果一个迭代器在另一个迭代器启动之前使用大部分或全部数据,则使用list()而不是tee()会更快。
在你的情况下恰好发生了什么:内部循环消耗所有数据,外部循环立即退出。
文档建议的解决方法:
gen = list(itertools.combinations(range(1, 6), 3))
for i in gen:
for j in gen:
print(i, j)
但当然这可能会占用大量内存,因为您从一开始就“杀死”了生成器功能。所以你使用组合而不是双循环的想法可能是最好的。