Python Join String to create combinations for all words in strings

If my string is: 'this is a string'

how can I create all the possible combinations by connecting each word with its adjacent word?

What this output looks like:

this is a string
thisis a string
thisisa string
thisisastring
thisis astring
this isa string
this isastring
this is astring

      

What I have tried:

s = 'this is a string'.split()    
for i, l in enumerate(s):
        ''.join(s[0:i])+' '.join(s[i:])

      

This gives:

'this is a string'
'thisis a string'
'thisisa string'
'thisisastring'

      

I understand that I need to change the part s[0:i]

because it is statically bound to 0, but I don’t know how to go to the next word is

while including this

in the output.

+3


source to share


4 answers


You can also use itertools.product () :



import itertools

s = 'this is a string'

words = s.split()
for t in itertools.product(range(len('01')), repeat=len(words)-1):
    print(''.join([words[i]+t[i]*' ' for i in range(len(t))])+words[-1])

      

+2


source


Well it took me a little longer than I expected ... it's actually harder than I thought :)

Main idea:

The number of spaces when splitting a string is the length or the divided array - 1. In our example, there are 3 spaces:

'this is a string'
     ^  ^ ^

      

We'll take a binary representation of all parameters to have / not have any of the spaces, so in our case it would be:



000
001
011
100
101
...

      

and for each option we will generate

offer accordingly, where 111 represents all 3 spaces: "this is a string" and 000 contains no spaces at all: "thisisastring"

def binaries(n):
    res = []
    for x in range(n ** 2 - 1):
        tmp = bin(x)
        res.append(tmp.replace('0b', '').zfill(n))
    return res


def generate(arr, bins):
    res = []
    for bin in bins:
        tmp = arr[0]
        i = 1
        for digit in list(bin):
            if digit == '1':
                tmp = tmp + " " + arr[i]
            else:
                tmp = tmp + arr[i]
            i += 1
        res.append(tmp)
    return res


def combinations(string):
    s = string.split(' ')
    bins = binaries(len(s) - 1)
    res = generate(s, bins)
    return res


print combinations('this is a string')
# ['thisisastring', 'thisisa string', 'thisis astring', 'thisis a string', 'this isastring', 'this isa string', 'this is astring', 'this is a string']

      

UPDATE:
Now I can see that Amadan was thinking the same idea - to be faster than I think! Great thoughts think the same;)

+2


source


A simpler (and 3x faster than the accepted answer) way of using the itertools product:

s = 'this is a string'
s2 = s.replace('%', '%%').replace(' ', '%s')
for i in itertools.product((' ', ''), repeat=s.count(' ')):
    print(s2 % i)

      

+2


source


The easiest way to do this is recursively.

  • Termination condition: A Schrödinger connection in one list of elements is a word.
  • Repeating condition: let's say L is the Schrödinger's union of all words, but the former. Then the Schrödinger union in the list consists of all elements from L with the first added first word and all elements from L with the first word added with an intermediate space.

(Suppose you accidentally lost it thisis astring

. If it's intentional, I'm sure I don't know what the question is: P)

Another, non-recursive way you can do this is to list all numbers from 0

to 2^(number of words - 1) - 1

, and then use the binary representation of each number as a selector, whether it should be present or not. So, for example, the above thisis astring

matches 0b010

, for "nospace, space, nospace".

+1


source







All Articles