In order combinations given a string

Viewed 47

I'm trying to create all possible in order combinations of a word's syllables.

For example, I have the word overflowing and I have a list of it's syllables ['o', 'ver', 'flow', 'ing']. I would like the output to show all the possible combinations of combining the syllables to make the word: [('o', 'ver', 'flow', 'ing'), ('o', 'verflow', 'ing'), ('o', 'verflowing'), ('overflowing'), ('over', 'flow', 'ing'), ...].

Here is my attempt:

syllable_list = ['o', 'ver', 'flow', 'ing']
list_length = len(syllable_list)
for x in range(0, list_length):
    for y in range(0, list_length):
        if syllable_list[y:x+1]:
            before = ""
            middle = ""
            after = ""
            if syllable_list[0:y]:
                before = ["".join(syllable_list[0:y])]
            if syllable_list[x+1:]:
                after = ["".join(syllable_list[x+1:])]
            middle = ["".join(syllable_list[y:x+1])]
            print(before, middle, after)

The output is:

 ['o'] ['verflowing']
 ['over'] ['flowing']
['o'] ['ver'] ['flowing']
 ['overflow'] ['ing']
['o'] ['verflow'] ['ing']
['over'] ['flow'] ['ing']
 ['overflowing']
['o'] ['verflowing']
['over'] ['flowing']
['overflow'] ['ing']

All the combinations are there, with some duplicates, and I'm missing the ['o', 'ver', 'flow', 'ing'] case. What am I doing wrong? Is there a library that already handles this so I don't have to recreate the wheel?

2 Answers

You can use a recursive generator which combines any two consecutive elements for the next level of recursion:

>>> def generate(parts, start=0):
...     yield parts
...     for i in range(start, len(parts)-1):
...         yield from generate([*parts[:i], parts[i]+parts[i+1], *parts[i+2:]], start=i)
... 
>>> from pprint import pprint
>>> pprint(list(generate(['o', 'ver', 'flow', 'ing'])))
[['o', 'ver', 'flow', 'ing'],
 ['over', 'flow', 'ing'],
 ['overflow', 'ing'],
 ['overflowing'],
 ['over', 'flowing'],
 ['o', 'verflow', 'ing'],
 ['o', 'verflowing'],
 ['o', 'ver', 'flowing']]

Since you defined only 3 variables (After, middle, and before) you can't get the output with more than 3 strings.

Your code will always join at least 2 strings.

You need to find another way to do this.

Related