扁平化itertools.product的结果

3 投票
1 回答
1452 浏览
提问于 2025-04-18 00:46

我有一些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 个回答

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...

撰写回答