我正在尝试实现自定义 itertools.product,因为我不创建整个笛卡尔积,但我希望修复最后几个元素。我只是从这里复制代码https://docs.python.org/3/library/itertools.html#itertools.product
def product(*args, repeat=1):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
并尝试定制。然而,即使没有任何改变,它的行为也不同于
for el in itertools.product(range(2), 30)
print(el)
案例1:我从文档中提供的代码片段(功能产品)。首先(如您所见的代码)创建整个结果,然后一个一个地产生。但是
案例2.
for el in itertools.product(range(2), 30)
print(el)
立即生成元素,这是我对生成器的期望,因为有时产品不适合我的记忆。
有人知道 itertools.product 的真正实现吗?
这非常接近实际实现:
def product(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
npools = len(pools)
try:
result = [pool[0] for pool in pools]
except IndexError:
return
yield result
indices = [0] * npools
p = npools - 1
while p >= 0:
pool = pools[p]
indices[p] += 1
try:
result[p] = pool[indices[p]]
except IndexError:
indices[p] = 0
result[p] = pool[indices[p]]
p -= 1
continue
else:
p = npools - 1
yield tuple(result)
这是应用于您的原始问题时的样子:
>>> big = product(range(2), repeat=30)
>>> next(big)
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> next(big)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
>>> next(big)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0)
>>> next(big)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)