Search code examples
pythonpython-3.xcombinationspython-itertools

Get all possible combination of values in a list -- Python


I have a list containing ['a', 'bill', 'smith'] and I would like to write a python code in order to obtain all possible combinations applying a certain criteria. To be more precise, I would like to obtain combination of those three element in the list plus the first letter of each element if that element isn't yet present in the output list. For example, given the list ['a', 'bill', 'smith'], one part of the expected output would be: ['a', 'bill', 'smith'], ['bill', 'smith'], ['a', 'smith'] but as well, ['a', 'b, 'smith'], ['bill, 's'], ['a', 's']. What I'm not expected to obtain is output like this ['s', 'bill, 'smith'] as the first element (s) is already taken into account by the third element ('smith'). Can someone help me?

This is what I've done so far:

mapping = dict(enumerate(['a', 'bill', 'smith']))
for i in mapping.items():
if len(i[1])>1:
    mapping[i[0]] = [i[1], i[1][0]]
else:
    mapping[i[0]] = [i[1]]

print(mapping)
{0: ['a'], 1: ['bill', 'b'], 2: ['william', 'w'], 3: ['stein', 's']}

I'm now stucked. I would like to use itertools library to iterate over the dict values to create all possible combinations.

Thanks in advance :)


Solution

  • You can use some itertools:

    from itertools import product, permutations
    
    lst = [list({s, s[:1]}) for s in ['a', 'bill', 'smith']]
    # [['a'], ['bill', 'b'], ['s', 'smith']]
    
    for perms in map(permutations, product(*lst)):
        for p in perms:
            print(p)
    
    ('a', 'bill', 's')
    ('a', 's', 'bill')
    ('bill', 'a', 's')
    ('bill', 's', 'a')
    ('s', 'a', 'bill')
    ('s', 'bill', 'a')
    ('a', 'bill', 'smith')
    ('a', 'smith', 'bill')
    ('bill', 'a', 'smith')
    ('bill', 'smith', 'a')
    ('smith', 'a', 'bill')
    ('smith', 'bill', 'a')
    ('a', 'b', 's')
    ('a', 's', 'b')
    ('b', 'a', 's')
    ('b', 's', 'a')
    ('s', 'a', 'b')
    ('s', 'b', 'a')
    ('a', 'b', 'smith')
    ('a', 'smith', 'b')
    ('b', 'a', 'smith')
    ('b', 'smith', 'a')
    ('smith', 'a', 'b')
    ('smith', 'b', 'a')
    

    The first step creates the list of equivalent lists:

    [['a'], ['bill', 'b'], ['s', 'smith']]
    

    then, product produces the cartesian product of the lists in said lists:

    ('a', 'bill', 's')
    ('a', 'bill', 'smith')
    ('a', 'b', 's')
    ...
    

    and for each of those, permutations gives you, well, all permutations:

    ('a', 'bill', 's')
    ('a', 's', 'bill')
    ('bill', 'a', 's')
    ...