如何迭代python中无限生成函数的无限笛卡尔积?
How to iterate through the infinite Cartesian product of infinite generator functions in python?
我想要一个生成器函数 product
生成任意两个给定生成器函数 f
和 g
的笛卡尔积(即如果 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)
...
我想要一个生成器函数 product
生成任意两个给定生成器函数 f
和 g
的笛卡尔积(即如果 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)
...