如何迭代python中无限生成函数的无限笛卡尔积?

How to iterate through the infinite Cartesian product of infinite generator functions in python?

我想要一个生成器函数 product 生成任意两个给定生成器函数 fg 的笛卡尔积(即如果 x 可以在 f()在有限时间内,y在有限时间内可以在g()中找到,那么(x,y)应该在有限时间内从product(f, g)中产生。

例如,我可能希望生成器函数遍历 (x,y) 满足 x in itertools.count() and y in itertools.count(-1, -1).

执行此操作的好方法是什么?任何顺序都可以。

这里有一个方法:

import itertools

def product(fn1, fn2):
    def product_part(fnx, fny):
      for i, x in enumerate(fnx()):
          for y in itertools.islice(fny(), i):
              yield x, y
    prod_a = zip(fn1(), fn2())
    prod_b = product_part(fn1, fn2)
    prod_c = ((x, y) for y, x in product_part(fn2, fn1))
    return itertools.chain.from_iterable(zip(prod_a, prod_b, prod_c))

基于 Gavin 早期的 self-product 解决方案,这是通过扩展访问对的“正方形”来实现的(如果您想象它们以 2D 形式布置,一个轴用于第一个生成器,另一个用于另一个生成器) .

from itertools import count, repeat

def product(f, g):
    for i, x, y in zip(count(), f(), g()):
        yield from zip(repeat(x, i), g())
        yield from zip(f(), repeat(y, i+1))

演示,正整数和负整数的乘积:

for p in product(lambda: count(1), lambda: count(-1, -1)):
    print(p)

输出(Try it online!):

(1, -1)
(2, -1)
(1, -2)
(2, -2)
(3, -1)
(3, -2)
(1, -3)
(2, -3)
(3, -3)
(4, -1)
(4, -2)
(4, -3)
(1, -4)
(2, -4)
(3, -4)
(4, -4)
(5, -1)
...