Search code examples
pythonlistpython-2.7tuplespython-itertools

Get product of lists of tuples by combining tuple elements?


I have a list of tuples that I am trying to get the product of by combining the individual tuple elements.

For example:

lists = [
    [(1,), (2,), (3,)],
    [(4,), (5,), (6,)]
]
p = itertools.product(*lists)
for product in p:
    print product

This results in a bunch of tuples of tuples:

((1,), (4,))
((1,), (5,))
((1,), (6,))
((2,), (4,))
((2,), (5,))
((2,), (6,))
((3,), (4,))
((3,), (5,))
((3,), (6,))

What I want is a list of tuples like so:

(1,4)
(1,5)
(1,6)
(2,4)
(2,5)
(2,6)
(3,4)
(3,5)
(3,6)

I also need this to hold for any number of initial lists of tuples.

So in the case of 3:

lists = [
    [(1,), (2,), (3,)],
    [(4,), (5,), (6,)],
    [(7,), (8,), (9,)]
]
p = itertools.product(*lists)
for product in p:
    print product

I'd like:

(1, 4, 7)
(1, 4, 8)
(1, 4, 9)
(1, 5, 7)
(1, 5, 8)
(1, 5, 9)
(1, 6, 7)
(1, 6, 8)
(1, 6, 9)
(2, 4, 7)
(2, 4, 8)
(2, 4, 9)
(2, 5, 7)
(2, 5, 8)
(2, 5, 9)
(2, 6, 7)
(2, 6, 8)
(2, 6, 9)
(3, 4, 7)
(3, 4, 8)
(3, 4, 9)
(3, 5, 7)
(3, 5, 8)
(3, 5, 9)
(3, 6, 7)
(3, 6, 8)
(3, 6, 9)

Solution

  • You can simply use itertools.chain.from_iterable to flatten the inner tuples, like this

    for product in p:
        print tuple(itertools.chain.from_iterable(product))
    

    For example,

    >>> from itertools import chain, product
    >>> [tuple(chain.from_iterable(prod)) for prod in product(*lists)]
    [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]