Generating all possible combinations of characters in a string

13,526

Solution 1

This looks like a job for itertools.product.

import itertools

def foo(l):
     yield from itertools.product(*([l] * 3)) 

for x in foo('abc'):
     print(''.join(x))

aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc

yield from is available to you from python3.3 and beyond. For older version, yield within a loop:

def foo(l):
     for i in itertools.product(*([l] * 3)) :
         yield i

Solution 2

The best way to get all combinations (also called cartesian product) of a list is to use itertools.product using the len of your iterable as repeat argument (that's where it differs from the other answer):

from itertools import product
li = ['a', 'b', 'c']
for comb in product(li, repeat=len(li)):
    print(''.join(comb))

or if you want the result as list:

>>> combs = [''.join(comb) for comb in product(li, repeat=len(li))]
>>> combs
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 
 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 
 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']

It's a bit cleaner to use the repeat argument than to multiply and unpack the list you have manually.

Solution 3

An alternate approach using list comprehension:

li = ['a', 'b', 'c']

new_li = [a+b+c for a in li for b in li for c in li]
Share:
13,526
James LT
Author by

James LT

Updated on June 27, 2022

Comments

  • James LT
    James LT almost 2 years

    Say I have a string list:

    li = ['a', 'b', 'c']
    

    I would like to construct a new list such that each entry of the new list is a concatenation of a selection of 3 entries in the original list. Note that each entry can be chosen repeatedly:

    new_li=['abc', 'acb', 'bac', 'bca', 'cab', 'cba', 'aab', 'aac',....'aaa', 'bbb', 'ccc']
    

    The brutal force way is to construct a 3-fold nested for loop and insert each 3-combination into the new list. I was wondering if there is any Pythonic way to deal with that? Thanks.

    Update: Later I will convert the new list into a set, so the order does not matter anyway.