2

I have a list of lists of tuples

A= [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]

The outer list can have any number of inner lists, the inner lists can have any number of tuples, a tuple always has 3 integers.

I want to generate all combination of tuples, one from each list:

[(1,2,3),(7,8,9),(2,1,0)]
[(1,2,3),(7,8,9),(1,3,5)]
[(1,2,3),(8,7,6),(2,1,0)]
...
[(4,5,6),(5,4,3),(1,3,5)]

A simple way to do it is to use a function similar to itertools.poduct() but it must be called like this

itertools.product([(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)])

i.e the outer list is removed. And I don't know how to do that. Is there a better way to generate all combinations of tuples?

5
  • How deep can the nested levels of lists be. Just 2, as in your example? Commented Nov 6, 2009 at 16:34
  • Duplicate: stackoverflow.com/search?q=%5Bpython%5D+flatten, stackoverflow.com/questions/120886/…, stackoverflow.com/questions/406121/… Commented Nov 6, 2009 at 16:38
  • @S Lott, related but not duplicates. (I thought so too, initially, the "flatten" keyword is misleading I think. Thought of editing title but didn't find a better expression; maybe "enumerate combinations"... Commented Nov 6, 2009 at 16:45
  • Maybe wrong word, but thought it was about "flatten" when I wrote the question. No, it is not homework. I got my degree '83, been working sice then. But new with python. trying to solve a quiz in a swedish newspaper lead to all my questions so far. Commented Nov 6, 2009 at 16:59
  • 2
    "Cartesian product" is maybe the word you're looking for. Commented Nov 8, 2009 at 20:27

7 Answers 7

10
itertools.product(*A)

For more details check the python tutorial

Sign up to request clarification or add additional context in comments.

Comments

2

This works for your example, if there is only one level of nested lists (no lists of lists of lists):

itertools.product(*A)

Comments

2

you can probably call itertools.product like so:

itertools.product(*A) # where A is your list of lists of tuples

This way it expands your list's elements into arguments for the function you are calling.

Comments

2

Late to the party but ...

I'm new to python and come from a lisp background. This is what I came up with (check out the var names for lulz):

def flatten(lst):
    if lst:
        car,*cdr=lst
        if isinstance(car,(list)):
            if cdr: return flatten(car) + flatten(cdr)
            return flatten(car)
        if cdr: return [car] + flatten(cdr)
        return [car]

Seems to work. Test:

A = [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]

flatten(A)

Result:

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

Note: the line car,*cdr=lst only works in Python 3.0

3 Comments

-1 The statement car,*cdr=lst isn't even legal Python. There is no direct syntax in Python to split a list in its head and tail (sorry 'bout that).
@ThomasH: It is valid in Python 3. See python.org/dev/peps/pep-3132. +1 to counteract needless downvote.
@StevenRumbalski Thanks for the pointer. I thought I was checking the Python 3 docs too, but obviously missed the *target.
1

This is not exactly one step, but this would do what you want if for some reason you don't want to use the itertools solution:

def crossprod(listoflists):
    if len(listoflists) == 1:
        return listoflists
    else:
        result = []
        remaining_product = prod(listoflists[1:])
        for outertupe in listoflists[0]:
            for innercombo in remaining_product[0]:
                newcombo = [outertupe]
                newcombo.append(innercombo)
                result.append(newcombo)
        return result

Comments

1
def flatten(A)
    answer = []
    for i in A:
        if type(i) == list:
            ans.extend(i)
        else:
            ans.append(i)
    return ans

2 Comments

you need to fix your indentation.
Terribly sorry for indentation errors. Turns out that copying code from my local IDE does not preserve proper indentation when I paste here
-1

This may also be achieved using list comprehension.

In [62]: A = [ [(1,2,3),(4,5,6)], [(7,8,9),(8,7,6),(5,4,3)],[(2,1,0),(1,3,5)] ]

In [63]: improved_list = [num for elem in A for num in elem]

In [64]: improved_list
Out[64]: [(1, 2, 3), (4, 5, 6), (7, 8, 9), (8, 7, 6), (5, 4, 3), (2, 1, 0), (1, 3, 5)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.