How find all combinations of two lists with python itertools, repeating one list but not the other

Question:

I have two lists, listA and listB. List C would be every value of list A paired with a value from list B (list B items can be repeated). I would like to find every possible combination of list C

listA = [1, 2, 3, 4, 5]
listB = ['a', 'b', 'c']
import itertools

listA = [1, 2, 3, 4, 5]
listB = ['a', 'b', 'c']

for item in itertools.permutations(x for x in itertools.product(listA,listB)):
    print(item)

Yields many lists like this:

((1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c'), (4, 'a'), (4, 'b'), (4, 'c'), (5, 'a'), (5, 'b'), (5, 'c')) 

What I would like it to yield is lists where items in listA are not repeated, like this:

((1, 'a'),  (2, 'a'),  (3, 'a'),  (4, 'a'), (5, 'a')),((1, 'b'),  (2, 'a'),  (3, 'a'),  (4, 'a'), (5, 'a')),((1, 'b'),  (2, 'b'),  (3, 'a'),  (4, 'a'), (5, 'a'))...

progressing further:

((1, 'b'),  (2, 'b'),  (3, 'b'),  (4, 'b'), (5, 'b')),((1, 'c'),  (2, 'b'),  (3, 'b'),  (4, 'b'), (5, 'b')),((1, 'c'),  (2, 'c'),  (3, 'b'),  (4, 'b'), (5, 'b')),

Extended desired output:

((1, 'a'),  (2, 'a'),  (3, 'a'),  (4, 'a'), (5, 'a')),
((1, 'b'),  (2, 'a'),  (3, 'a'),  (4, 'a'), (5, 'a')),
((1, 'b'),  (2, 'b'),  (3, 'a'),  (4, 'a'), (5, 'a')),
((1, 'b'),  (2, 'b'),  (3, 'b'),  (4, 'a'), (5, 'a')),
((1, 'b'),  (2, 'b'),  (3, 'b'),  (4, 'b'), (5, 'a')),
((1, 'b'),  (2, 'b'),  (3, 'b'),  (4, 'b'), (5, 'b')),
((1, 'c'),  (2, 'b'),  (3, 'b'),  (4, 'b'), (5, 'b')),
((1, 'c'),  (2, 'c'),  (3, 'b'),  (4, 'b'), (5, 'b')),
...
((1, 'c'),  (2, 'c'),  (3, 'c'),  (4, 'c'), (5, 'c')),
((1, 'a'),  (2, 'c'),  (3, 'c'),  (4, 'c'), (5, 'c')),
((1, 'a'),  (2, 'a'),  (3, 'c'),  (4, 'c'), (5, 'c')),
((1, 'a'),  (2, 'a'),  (3, 'a'),  (4, 'c'), (5, 'c')),
...
((1, 'a'),  (2, 'b'),  (3, 'c'),  (4, 'c'), (5, 'c')),
...
((1, 'a'),  (2, 'a'),  (3, 'c'),  (4, 'c'), (5, 'c')),
...
((1, 'c'),  (2, 'c'),  (3, 'c'),  (4, 'c'), (5, 'a')),
...
Asked By: Prograde

||

Answers:

You could zip listA with each combination produced by the product function on listB with as many repeats as the size of listA:

listA = [1, 2, 3, 4, 5]
listB = ['a', 'b', 'c']

from itertools import product

listC = ( tuple(zip(listA,combo))
          for combo in product(listB,repeat=len(listA)))

for c in listC: print(c)

    
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'b'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'c'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'a'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'b'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'c'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'a'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'b'))
((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'c'))
((1, 'a'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'a'))
...
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'a'), (5, 'a'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'a'), (5, 'b'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'a'), (5, 'c'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'b'), (5, 'a'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'b'), (5, 'b'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'b'), (5, 'c'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'a'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'b'))
((1, 'c'), (2, 'c'), (3, 'c'), (4, 'c'), (5, 'c'))
Answered By: Alain T.

To achieve the desired output, you can use itertools.product() to generate all possible combinations of listA and listB, and then use a nested loop to iterate over each element in listA and create a list of tuples containing the current element and all the elements from listB.

Here’s an example code that should achieve the desired output:

import itertools

listA = [1, 2, 3, 4, 5]
listB = ['a', 'b', 'c']

# Generate all possible combinations of listA and listB
combinations = list(itertools.product(listA, listB))

# Create a list of tuples for each element in listA
result = []
for a in listA:
    temp = []
    for c in combinations:
        if c[0] == a:
            temp.append(c)
    result.append(tuple(temp))

# Print the result
for r in result:
    print(r)
Answered By: Anil Khatiwada

I’ve got a disgusting 1-liner using primarily itertools. Probably not the best for production code, but should suffice for a quick script-

from itertools import repeat, product
listC = list(zip(*map(zip, map(repeat, listA), zip(*product(listB, repeat=len(listA))))))

Output:

[((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'b'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'a'), (4, 'c'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'a'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'b'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'b'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'b'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'c'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'c'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'b'), (4, 'c'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'a'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'a'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'a'), (5, 'c')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'b'), (5, 'a')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'b'), (5, 'b')), ((1, 'a'), (2, 'a'), (3, 'c'), (4, 'b'), (5, 'c')), ...]
Answered By: Dillon Davis