Posts: 4,647
Threads: 1,494
Joined: Sep 2016
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']
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 817
Threads: 1
Joined: Mar 2018
It is Cartesian product of sets:
from itertools import product
list(map(''.join, product('abc', 'def','hg')))
Posts: 4,647
Threads: 1,494
Joined: Sep 2016
i'm looking for something that can (also) parse that particular syntax.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 95
Threads: 3
Joined: May 2019
What do you mean by "parse that particular syntax"?
Posts: 4,647
Threads: 1,494
Joined: Sep 2016
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.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 95
Threads: 3
Joined: May 2019
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']
Posts: 4,647
Threads: 1,494
Joined: Sep 2016
May-22-2019, 05:03 AM
(This post was last modified: May-22-2019, 05:04 AM by Skaperen.)
try this: print(len(string_combos('{0,1,2}'*15)))
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Posts: 95
Threads: 3
Joined: May 2019
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 .
Posts: 4,647
Threads: 1,494
Joined: Sep 2016
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.
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
|