Search code examples
pythonlistpython-itertools

How can I find all ways of pairing elements between two lists of equal length?


Suppose I have two input lists like:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

I want to get a list of lists of tuples, of all the potential combinations between the two - i.e., of ways to pair all the elements up. Thus, the result should be like:

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

That is: the first list shows the 1 being paired with the 4, the 2 with the 5, and the 3 with the 6. There are 6 lists, corresponding to all the ways that the elements from list1 could be associated with the elements of list2.

I think the itertools standard library should be helpful here, but I couldn't figure out a solution. I got this far:

list1 = [1, 2, 3]
list2 = [5, 6, 7]
print(list(itertools.product(list1, list2)))

but the result is:

[(1, 5), (1, 6), (1, 7), (2, 5), (2, 6), (2, 7), (3, 5), (3, 6), (3, 7)]

It shows every possible pairing of an element from list1 with an element of list2, but not the possible resulting lists composed from these pairing.

How can I fix the code?


Solution

  • repeat the first list, permutate the second and zip it all together

    >>> from itertools import permutations, repeat
    >>> a = [1, 2, 3]
    >>> b = [4, 5, 6]
    >>> list(list(zip(r, p)) for (r, p) in zip(repeat(a), permutations(b)))
    [[(1, 4), (2, 5), (3, 6)],
     [(1, 4), (2, 6), (3, 5)],
     [(1, 5), (2, 4), (3, 6)],
     [(1, 5), (2, 6), (3, 4)],
     [(1, 6), (2, 4), (3, 5)],
     [(1, 6), (2, 5), (3, 4)]]
    

    EDIT: As Peter Otten noted, the inner zip and the repeat are superfluous.

    [list(zip(a, p)) for p in permutations(b)]