Python连接字符串以生成字符串中所有单词的组合

时间:2015-04-20 03:46:26

标签: string python-3.x join combinations

如果我的字符串是:'this is a string',如何通过将每个单词与其相邻单词连接来生成所有可能的组合?

此输出的外观如下:

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

我尝试过:

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

这会产生:

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

我意识到我需要更改s[0:i]部分,因为它已静态固定为0但我不知道如何移动到下一个单词is,同时仍然包括this输出中的{1}}。

4 个答案:

答案 0 :(得分:3)

使用itertools产品的方式更简单(并且比接受的答案快3倍):

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

答案 1 :(得分:2)

嗯,我花了比预想的更长的时间......这实际上比我想象的要快一点:)

主要观点:

分割字符串时的空格数是长度或拆分数组 - 1.在我们的示例中有3个空格:

'this is a string'
     ^  ^ ^

我们将所有选项的二进制表示包含/不包含其中一个空格,因此在我们的例子中它将是:

000
001
011
100
101
...

并且对于每个选项,我们将分别generate句子,其中111表示所有3个空格:'这是一个字符串',000表示根本没有空格:'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']

<强>更新
我现在看到Amadan想到了同样的想法 - 感觉比我更快思考!伟大的思想相似;)

答案 2 :(得分:2)

您还可以使用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])

答案 3 :(得分:1)

最简单的是以递归方式进行。

  • 终止条件:单个元素列表的Schrödinger连接就是那个词。
  • 重复的条件:说L是所有单词的Schrödinger连接,但第一个。然后,列表的薛定谔连接由L中的所有元素组成,第一个单词直接前置,而L中的所有元素都带有第一个单词,前面有一个插入空间。

(假设你偶然失踪thisis astring。如果是故意的,我相信我不知道问题是什么:P)

你可以做的另一种非递归方式是枚举从02^(number of words - 1) - 1的所有数字,然后使用每个数字的二进制表示作为选择器,无论空间是否需要当下。因此,例如,上述thisis astring对应于0b010,对于“nospace,space,nospace”。