3

I have two list:

list1 = ["A", "B", "C", "D", "E"]
list2 = ["AA", "BB", "CC", "DD", "EE"]

I want to create every possible combination, as the following:

    A-B-C-D-E
    A-BB-C-D-E
    A-B-C-DD-E...etc.

The rule is that two similar letter (like A-AA, B-BB) can't be in the combination at the same time, and the order is reversible (A-B-C-D-E and B-A-E-C-D is the same in content so i don't need them both)

How can I manage it with itertools?

2
  • I'm not sure I follow what you want. If I understand you correctly, you want, given two lists a and b of length of N, to create N lists of length N, such that the ith list is a copy of list a, but with the ith entry replaced with the ith entry of list b? Is the omission of AA-B-C-D-E and A-B-CC-D-E intentional? Commented Jun 6, 2021 at 21:52
  • Can A-BB-CC-D-E be in the output? Your sample output makes me assume that at most only one item of two character list is allowed for a given item. Commented Jun 6, 2021 at 22:29

1 Answer 1

7

TL;DR: map('-'.join, product(*zip(list1, list2))).


It's relatively simple to do using itertools, but you have to think through each step carefully.

First, you can zip your two lists together to get a sequence of tuples. Every element in your final result will include exactly one choice from each tuple.

>>> list1 = ["A", "B", "C", "D", "E"]
>>> list2 = ["AA", "BB", "CC", "DD", "EE"]
>>> list(zip(list1, list2))
[('A', 'AA'), ('B', 'BB'), ('C', 'CC'), ('D', 'DD'), ('E', 'EE')]

Next, we'll want the Cartesian product of each of the five tuples. This gives us the 32 different ways of choosing one of A or AA, then one of B or BB, etc. To do that, we use * to unpack the result of zip into five separate arguments for product.

>>> from itertools import product
>>> for x in product(*zip(list1, list2)):
...   print(x)
...
('A', 'B', 'C', 'D', 'E')
('A', 'B', 'C', 'D', 'EE')
('A', 'B', 'C', 'DD', 'E')
('A', 'B', 'C', 'DD', 'EE')
('A', 'B', 'CC', 'D', 'E')
('A', 'B', 'CC', 'D', 'EE')
('A', 'B', 'CC', 'DD', 'E')
# etc

Once you have the product, each element of the product is a valid argument to '-'.join to create one of the strings in your desired set:

>>> for x in map('-'.join, product(*zip(list1, list2))):
...   print(x)
...
A-B-C-D-E
A-B-C-D-EE
A-B-C-DD-E
A-B-C-DD-EE
A-B-CC-D-E
A-B-CC-D-EE
A-B-CC-DD-E
A-B-CC-DD-EE
A-BB-C-D-E
A-BB-C-D-EE
A-BB-C-DD-E
A-BB-C-DD-EE
A-BB-CC-D-E
A-BB-CC-D-EE
A-BB-CC-DD-E
A-BB-CC-DD-EE
AA-B-C-D-E
AA-B-C-D-EE
AA-B-C-DD-E
AA-B-C-DD-EE
AA-B-CC-D-E
AA-B-CC-D-EE
AA-B-CC-DD-E
AA-B-CC-DD-EE
AA-BB-C-D-E
AA-BB-C-D-EE
AA-BB-C-DD-E
AA-BB-C-DD-EE
AA-BB-CC-D-E
AA-BB-CC-D-EE
AA-BB-CC-DD-E
AA-BB-CC-DD-EE
Sign up to request clarification or add additional context in comments.

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.