Python Forum

Full Version: list of string combinations
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
the bash shell for Unix has a feature that allows using a text token like {a,b}{c,d}{e,f} and produces all combinations as if ace acf ade adf bce bcf bde bdf had been used in its place. has anyone seen or written a Python function that can do this to a string, maybe returning a list, such as:

string_combos('{a,b}{c,d}{e,f}') => ['ace','acf','ade','adf','bce','bcf','bde','bdf']
It is Cartesian product of sets:

from itertools import product
list(map(''.join, product('abc', 'def','hg')))
i'm looking for something that can (also) parse that particular syntax.
What do you mean by "parse that particular syntax"?
look at the function call i showed and the string being passed to the function. this is the syntax that works in bash. i want to support that syntax in programs i write that take user input.
from itertools import product
import re

def string_combos(s):
    # get all expressions inside brackets into a list
    brackets = re.findall(r'{(.+?)}', s)

    # remove comas 
    joined_chars_list = [''.join(b.split(',')) for b in brackets]

    # In the above line the b.split(',') could be turned into another
    # list comprehension to remove whitespace if it is acceptable as
    # a part of input string

    # E.g. if this is acceptable:
    # string_combos('{a, b}{ c , d}{ e,   f}')

    # Then use something like:
    # [char_part.strip() for char_part in b.split(',')]
    
    return [''.join(p) for p in product(*joined_chars_list)] # copy of what scidam posted but I find this way easier to read than "list(map(" way
    
result = string_combos('{a,b}{c,d}{e,f}')
print(result)
Output:
['ace', 'acf', 'ade', 'adf', 'bce', 'bcf', 'bde', 'bdf']
try this: print(len(string_combos('{0,1,2}'*15)))
What for?

Output of this line in bash:
echo {0,1,2}{0,1,2}

is the same as output of this line in the python program posted above:
string_combos('{0,1,2}{0,1,2}')

So I assume it works as expected.

'{0,1,2}'*15 in python evaluates to '{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}{0,1,2}'

The input you're suggesting to test is taking ages to compute in bash (by prepending it with 'echo'), and ages to compute in python code I posted because there's just too many combinations. I don't get what's your point...

Or did you mean to test '{0,1,2}*15' (where *15 is included within the string)?
In such case I'd suggest to use subprocess to just execute it with bash using echo.
my point is diversity in testing. i guess my computer is faster or has more RAM to swap less since it only took about 3.9 seconds for me. i wanted to be sure that the code was not limited to the scope of my original example. i ran it here on Python 3.5.2 on Ubuntu 16.04.6.