Home > Software engineering >  Combination of entries from N lists
Combination of entries from N lists

Time:04-13

I have N lists [the size of each list might vary] in python. The value of N itself might vary too.

Let us consider an example where the number of lists are 3 [for simplicity, each list has size 2]:

[A, B], [C, D], [E, F]

Now what I am expecting is something like this:

ACE, ADE, ACF, ADF, BCE, BDE, BCF, BDF

A combination of each entry from all the lists [we will avoid combining entries from the same list].

What would be the most efficient way of solving this problem? [I am unsure if a similar problem is available online, as I wasn't able to find one].

CodePudding user response:

Running this code:

from itertools import product
from functools import reduce

def combine_words(list1, list2):
    word_pairs = product(list1, list2)
    combined_words = []
    for pair in word_pairs:
        combined_words.append("".join(pair))
    return combined_words

reduce(combine_words, [["A", "B"], ["C", "D"], ["E", "F"]])

Will return the following result:

['ACE', 'ACF', 'ADE', 'ADF', 'BCE', 'BCF', 'BDE', 'BDF']

It works regardless of the number of words in each list, or regardless of the number of lists inside the total list.

CodePudding user response:

itertools.product does exactly what you need:

##separate lists
ls1 = ['A','B']
ls2 = ['C','D']
ls3 = ['E','F','G']
out = list(product(ls1,ls2,ls3))

##or, list of lists, using the * operator
ls = [['A','B'],['C','D'],['E','F','G']]
out = list(product(*ls))

##in both cases
print(out)
[('A', 'C', 'E'), ('A', 'C', 'F'), ('A', 'C', 'G'), ('A', 'D', 'E'), ('A', 'D', 'F'), ('A', 'D', 'G'), ('B', 'C', 'E'), ('B', 'C', 'F'), ('B', 'C', 'G'), ('B', 'D', 'E'), ('B', 'D', 'F'), ('B', 'D', 'G')]

CodePudding user response:

It turns out to be a product rather than a combination problem.

Because Python strings can be iterated over as if they were a list of characters this leads to several ways in which the input could be stated. (I like the third way as it can be less typing if spaces are not in any of the "words").

Code

from itertools import product
from typing import List, Union

def word_product(list_of_lists: Union[List[List[str]], List[str]]) -> str:
    return ', '.join(''.join(values) for values in product(*list_of_lists))

example1 = [["A", "B"], ["C", "D"], ["E", "F"]]
print(word_product(example1))

example2 = ["AB", "CD", "EF"]
print(word_product(example2))

example3 = "AB CD EF".split()
print(word_product(example3))

Output

It is the same line for each of the equivalent example inputs:

ACE, ACF, ADE, ADF, BCE, BCF, BDE, BDF
ACE, ACF, ADE, ADF, BCE, BCF, BDE, BDF
ACE, ACF, ADE, ADF, BCE, BCF, BDE, BDF
  • Related