使用 itertools.combinations 从某个值开始在 3 个维度 i、j、k 中继续迭代

Continue iteration in 3 dimensions i, j, k using itertools.combinations from certain value

我 post 这个问题,因为所有现有的答案都使用 islice 在一个维度上解决了这个问题,这是不一样的(至少我不知道如何将当前的解决方案转移到三个维度)。

假设我们有以下脚本生成三个维度(1 到 127)的整数的所有离散组合:

for j, k, l in itertools.combinations(range(1, 128), 3):
    result = calculations([128, i, j, k, 0])
    writeFile(result+"\n")

并假设脚本在随机(记录的)点中断,例如[128, 121, 98, 45]。我们如何使用 islice(或任何其他库)继续下一次迭代,即 [128, 121, 98, 46] 及之后直到 [128,127,126,125]?

感谢您的宝贵时间,

作为一个有点肮脏的 hack,iter(f, sentinel) 生成一个重复调用给定函数的迭代器,直到它 returns 给定的标记值,所以如果你知道最后完成的值,你可以传递 combos.__next__ 和最后给定的值 iter 并耗尽该迭代器以跳到下一个可行的项目:

import itertools, collections
all_combos = iter(map(set, itertools.combinations(range(1, 128), 3)))
LAST_RECORDED_COMBO = {121, 98, 45}
ITER_WE_WANT_TO_SKIP = iter(all_combos.__next__, LAST_RECORDED_COMBO)
# taken right from 
collections.deque(ITER_WE_WANT_TO_SKIP, maxlen=0)

for combo in all_combos: # all_combos has now skipped forward
    print(combo) # original loop etc.

以上只是循环遍历组合,当它看到最后一个这样使用时停止:

for c in all_combos:
    if c == LAST_RECORDED_COMBO:
        break
for combo in all_combos: # all_combos has now skipped forward
    print(combo) # original loop etc.

但是进行了优化,因此它可以 运行 完全在 C 层上,就像 islice 一样有助于提高性能。

我在这里使用 map(set, ..) 是因为哨兵值必须相等,这意味着列表或元组的顺序对于它正确停止很重要,否则这会产生非常糟糕的反馈,因为它会耗尽整个没有明确说明原因的迭代器。