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.
source to share
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])
source to share
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;)
source to share
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".
source to share