定制产品需要真正实现 itertools.product

问题描述 投票:0回答:1

我正在尝试实现自定义 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 的真正实现吗?

python generator product python-itertools
1个回答
0
投票

这非常接近实际实现

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)
© www.soinside.com 2019 - 2024. All rights reserved.