Search code examples
pythonarrayslistpython-2.7python-itertools

Python: 2-item combinations from list of lists containing 1 or more items


I want to find all 2-item combinations from a list of lists. The inner lists contain one or more items, and I don't want to include combinations of items within the same inner list (unless that combination exists within separate inner lists).

Is there a way to utilize the built in functions from itertools to arrive at my desired combination requirements, or do I need to write the for loops from scratch?

Here's a very simple example:

x = [['219'], ['220'], ['218']]
# find combos
print combos
>> [['219', '220'], ['219', '218'], ['220', '218']]

The list could contain lists with more than one item. Here's a more complex example where the inner lists contain more than 1 item:

x = [['222', '219'], ['221'], ['220', '218', '216']]
# find combos
print combos 
>> [['222', '221'], ['222', '220'], ['222', '220'], ['222', '218'], ['222', '216'], ['219', '221'], ['219', '220'], ['219', '218'], ['219', '216'], ['221', '220'], ['221', '218'], ['221', '216']]

Solution

  • How about this one-liner?

    from itertools import combinations, product, chain
    
    x = [['222', '219'], ['221'], ['220', '218', '216']]
    combos = list(chain.from_iterable( [list(product(a,b)) for (a,b) in combinations(x,2)]))
    

    Edit: roippi is absolutely correct. We can get rid of unnecessary intermediates by

    combos = list(chain.from_iterable(product(*c) for c in combinations(x,2)))