从itertools.product中展平结果

时间:2014-04-01 03:31:17

标签: python

我有一些像

这样的python代码
from itertools import product
myItems = product(*groups.values())

这给了我itertools.product对象,当我迭代时,它看起来像

(myCustomObject,myCustomObject,myCustomObject(myCustomObject,myCustomObject,myCustomObject))

如何展平此对象以使其看起来像

(myCustomObject,myCustomObject,myCustomObject,myCustomObject,myCustomObject,myCustomObject)

我想迭代对象而不是把它放在列表中,因为myItems对象包含数十亿条记录。最有效的方法是什么?

1 个答案:

答案 0 :(得分:4)

itertools.product的输出是一个会产生元组的对象:

>>> list(itertools.product('ABCD', 'XYZ'))
[('A', 'X'), ('A', 'Y'), ('A', 'Z'), ('B', 'X'), ('B', 'Y'), ('B', 'Z'), ('C', 'X'), ('C', 'Y'), ('C', 'Z'), ('D', 'X'), ('D', 'Y'), ('D', 'Z')]

假设您想要展平product生成的所有元组,请使用chain

>>> list(itertools.chain.from_iterable(itertools.product('ABCD', 'XYZ')))
['A', 'X', 'A', 'Y', 'A', 'Z', 'B', 'X', 'B', 'Y', 'B', 'Z', 'C', 'X', 'C', 'Y', 'C', 'Z', 'D', 'X', 'D', 'Y', 'D', 'Z']

如果馈送到product的对象本身是嵌套的元组或列表,product将不会以递归的方式进入它们:

>>> list(itertools.product('ABCD', ['w', 'x',['y','z']]))
[('A', 'w'), ('A', 'x'), ('A', ['y', 'z']), ('B', 'w'), ('B', 'x'), ('B', ['y', 'z']), ('C', 'w'), ('C', 'x'), ('C', ['y', 'z']), ('D', 'w'), ('D', 'x'), ('D', ['y', 'z'])]

如果要展平任意深度列表,则需要递归执行:

def flatten(container):
    for i in container:
        if isinstance(i, list) or isinstance(i, tuple):
            for j in flatten(i):
                yield j
        else:
            yield i

>>> list(flatten(itertools.product('ABCD', ['w', 'x',['y','z']])))     
['A', 'w', 'A', 'x', 'A', 'y', 'z', 'B', 'w', 'B', 'x', 'B', 'y', 'z', 'C', 'w', 'C', 'x', 'C', 'y', 'z', 'D', 'w', 'D', 'x', 'D', 'y', 'z']

虽然老实说,我不能想到一个用例,它有一个嵌套的深度不同的对象列表,以便首先提供给product ...