Reputation: 41
I have an array of n words as strings such as:
input: ["just", "a", "test"]
What I need to do is create all possible combinations of these words separated by spaces as well as in combination with the original strings. For example, the above should create:
output: [["just", "a", "test"], ["just a", "test"], ["just a test"], ["just", "a test"]]
I've been using itertools but can't get it to do what I need. What I have at the moment:
iterable = ['just', 'a', 'test']
for n in chain.from_iterable(combinations(iterable, n) for n in range(len(iterable)+1)):
print(n)
The following almost works as required:
iterable = ['just', 'a', 'test']
L = [''.join(reversed(x)).rstrip()
for x in product(*[(c, c+' ') for c in reversed(iterable)])]
print(L)
Thank you.
EDIT:
To clarify how this should work for an array of length 4: input: ['an', 'even', 'bigger', 'test']`
output:
['an', 'even', 'bigger', 'test']
['an even', 'bigger', 'test']
['an even bigger', 'test']
['an even bigger test']
['an', 'even bigger', 'test']
['an even', 'bigger test']
['an', 'even bigger test']
['an', 'even', 'bigger test']
Upvotes: 4
Views: 909
Reputation: 1737
You can try this (compatible for both python 2.x and python 3.x):
s = ["this", "is", "just", "a", "simple", "test"] # the input
sepCount = len(s) - 1 # separator count of the input
output = [] # output
for i in range(0, 2 ** sepCount): # iterate through all possible combinations
t = s # modified string
j = i # for converting to binary
for k in reversed(range(sepCount)):
if j % 2 == 0:
t = t[ : k] + [" ".join(t[k : k + 2])] + t [k + 2 :] # replace separator to " "
j = j // 2
output.append(t)
print(output)
Output:
[['this is just a simple test'],
['this is just a simple', 'test'],
['this is just a', 'simple test'],
['this is just a', 'simple', 'test'],
['this is just', 'a simple test'],
['this is just', 'a simple', 'test'],
['this is just', 'a', 'simple test'],
['this is just', 'a', 'simple', 'test'],
['this is', 'just a simple test'],
['this is', 'just a simple', 'test'],
['this is', 'just a', 'simple test'],
['this is', 'just a', 'simple', 'test'],
['this is', 'just', 'a simple test'],
['this is', 'just', 'a simple', 'test'],
['this is', 'just', 'a', 'simple test'],
['this is', 'just', 'a', 'simple', 'test'],
['this', 'is just a simple test'],
['this', 'is just a simple', 'test'],
['this', 'is just a', 'simple test'],
['this', 'is just a', 'simple', 'test'],
['this', 'is just', 'a simple test'],
['this', 'is just', 'a simple', 'test'],
['this', 'is just', 'a', 'simple test'],
['this', 'is just', 'a', 'simple', 'test'],
['this', 'is', 'just a simple test'],
['this', 'is', 'just a simple', 'test'],
['this', 'is', 'just a', 'simple test'],
['this', 'is', 'just a', 'simple', 'test'],
['this', 'is', 'just', 'a simple test'],
['this', 'is', 'just', 'a simple', 'test'],
['this', 'is', 'just', 'a', 'simple test'],
['this', 'is', 'just', 'a', 'simple', 'test']]
The motive: there are n-1 separators (,
) for a list of length n. There are 2^(n-1) ways of replacing the ,
s with an empty space. By iterating all these 2^(n-1) possible ways, you can generate all possible combinations of these words separated by spaces.
Upvotes: 1
Reputation: 164673
This is one solution. The partitions
function is courtesy of @Kiwi.
from itertools import combinations
iterable = ['just', 'a', 'test', 'and', 'another']
n = len(iterable)
def partitions(items, k):
def split(indices):
i=0
for j in indices:
yield items[i:j]
i = j
yield items[i:]
for indices in combinations(range(1, len(items)), k-1):
yield list(split(indices))
for i in range(1, n+1):
for x in partitions(iterable, i):
print([' '.join(y) for y in x])
['just a test and another']
['just', 'a test and another']
['just a', 'test and another']
['just a test', 'and another']
['just a test and', 'another']
['just', 'a', 'test and another']
['just', 'a test', 'and another']
['just', 'a test and', 'another']
['just a', 'test', 'and another']
['just a', 'test and', 'another']
['just a test', 'and', 'another']
['just', 'a', 'test', 'and another']
['just', 'a', 'test and', 'another']
['just', 'a test', 'and', 'another']
['just a', 'test', 'and', 'another']
['just', 'a', 'test', 'and', 'another']
Upvotes: 1