Home > Net >  Create words by combining all elements in a set of lists with each other
Create words by combining all elements in a set of lists with each other

Time:03-15

I have 6 different lists, which I need to combine and create sequences/words for all possible combinations.

These are my lists:

product = ['SOC', 'SOCCAMP', 'ETI', 'CARDASS', 'VRS', 'PRS', 'INT', 'GRS', 'VeloVe', 'HOME']
fam = ['IND', 'FAM']
area = ['EUR', 'WOR']
type = ['STD', 'PLU']
assist = ['MOT', 'NMOT']

All of the elements in all of the lists need to be combined in words. The result will be a list of all the elements possible. I will have among all of the elements f.e. the following words: ('SOC', 'SOCIND', 'SOCFAM', 'SOCFAMMOT', 'SOCMOTFAM'...)

I thus combine each element of a precise list with all the elements of the other lists.

Up to now I managed to combine them with a series of loops:

combos = []

##1##
for i in range(len(product)):
    combos.append(str(product[i]))

##2##
for a in range(len(product)):
        for b in range(len(fam)):
            combos.append(str(product[a])   str(fam[b]))

##3##
for a in range(len(product)):
    for b in range(len(fam)):
        for c in range(len(area)):
            combos.append(str(product[a])   str(fam[b])   str(area[c]))

##4##
for a in range(len(product)):
    for b in range(len(fam)):
        for c in range(len(area)):
            for d in range(len(type)):
                combos.append(str(product[a])   str(fam[b])   str(area[c])   str(type[d]))

##5##
for a in range(len(product)):
    for b in range(len(fam)):
        for c in range(len(area)):
            for d in range(len(type)):
                for e in range(len(assist)):
                    combos.append(str(product[a])   str(fam[b])   str(area[c])   str(type[d])   str(assist[e]))

This code manages to combine the words in a list of combinations but solely in the precise order the lists are mentioned:

['SOC', 'SOCCAMP', 'ETI', 'CARDASS', 'VRS', 'PRS', 'INT', 'GRS', 'VeloVe', 'HOME', 'SOCIND', 'SOCFAM', 'SOCCAMPIND', 'SOCCAMPFAM', 'ETIIND', 'ETIFAM', 'CARDASSIND', 'CARDASSFAM', 'VRSIND', 'VRSFAM', 'PRSIND', 'PRSFAM', 'INTIND', 'INTFAM', 'GRSIND', 'GRSFAM', 'VeloVeIND', 'VeloVeFAM', 'HOMEIND', 'HOMEFAM', ...]

So, 'SOCINDEUR' is a combination in this list but 'SOCEURIND' is not.

Is there a smart way to avoid writing down another 100 loops to look for all the possible combinations?

CodePudding user response:

You can make use of various tools provided by itertools.

Overall, one solution is:

source_lists = product, fam, area, type, assist
combos = [
    ''.join(prod) 
    for l in range(1, len(source_lists)) 
    for subset in itertools.permutations(source_lists, l) 
    for prod in itertools.product(*subset) 
]

This code is effectively equivalent of:

combos = []
source_lists = product, fam, area, type, assist
for l in range(1, len(source_lists)):
    for subset in itertools.permutations(source_lists, l):
        for prod in itertools.product(*subset):
            combos.append(''.join(prod))

The first loop selects how many different source lists you want to select, so it will first produce the results from single list, i.e. the "original" input. Then it moves to combining two etc.

The second loop select which source lists and in which order we will combine (and goes over all possible permutations).

Finally the third and last loop takes the selected source list and produces all the possible combinations (or, better said "product") of these lists.

Finally this produces the tuples of results, since you want one single string per result, we need to join them.

CodePudding user response:

The magic of itertools!

from itertools import product, permutations

def concat_combinations(sequence):
     new_seq = []
     for i,j in enumerate(sequence):
         if i == 0:
             new_str = j
             new_seq.append(new_str)
         else:
             new_str  = j
             new_seq.append(new_str)
     return new_seq

def final_list(*iterables)->list:
    s = set()
    for seq in list(product(*iterables)):
       [s.update(concat_combinations(i)) for i in permutations(seq)]
    return sorted(s,key=lambda x: len(x))
  • Related