itertools.product - 返回列表而不是元组

时间:2014-04-05 16:10:25

标签: python itertools

我希望itertools.product返回列表而不是元组。我目前通过创建我自己的函数来实现它:

def product_list(*args, **kwds):
    # 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 = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x + [y] for x in result for y in pool]
    for prod in result:
        yield list(prod)  # Yields list() instead of tuple()

代码来自Python文档 - 我刚刚修改了最后一行。这很好但但似乎并不聪明。

这样做的其他方法是什么?我正在考虑使用类似decorator的东西或者用我自己的生成器函数包装它。我对这两个概念都不太熟悉,如果有人能给我看,我会很感激。

修改 我做这样凌乱的事情:

for r0 in product_list([0, 1], repeat=3):
    r0.insert(0, 0)
    for r1 in product_list([0, 1], repeat=3):
        r1.insert(1, 0)
        for r2 in product_list([0, 1], repeat=3):
            r2.insert(2, 0)
            for r3 in product_list([0, 1], repeat=3):
                r3.insert(3, 0)

所以我希望我的函数返回一个列表,而不是每次都要抛出它。 (我知道代码很乱,需要递归,但我会稍后考虑一下。我更感兴趣的是学习如何做我上面描述的内容)

1 个答案:

答案 0 :(得分:6)

itertools.product是一个生成器,您可以轻松地将生成器链接在一起。这是一个生成器表达式,它将product产生的每个元组更改为一个列表:

(list(tup) for tup in itertools.product(iterable1, iterable2, etc))

在您的示例代码中,您可以使用生成器表达式,或者您可以使用不同的方法在值的前面添加额外的值,同时将它们保留为元组:

for r0 in itertools.product([0, 1], repeat=3):
    r0 = (0,) + r0 # keep r0 a tuple!
    for r1 in itertools.product([0, 1], repeat=3):
        r1 = (1,) + r1 # same here
        # ...

由于您没有显示您使用rN变量的内容,因此无法就最佳方式给出明确答案。 (这有点代码味道,你有编号变量。)的确,因为你的循环只是计算三个01数字,你可能能够逃脱一个{ {1}}调用,一次性生成product个不同n值的列表:

r