2013-12-24 239 views
22

给定一个字符串,我想要生成所有可能的组合。换句话说,所有可能的方式都是在字符串的某个位置放置一个逗号。分隔字符串

例如:

input: ["abcd"] 
output: ["abcd"] 
     ["abc","d"] 
     ["ab","cd"] 
     ["ab","c","d"] 
     ["a","bc","d"] 
     ["a","b","cd"] 
     ["a","bcd"] 
     ["a","b","c","d"] 

我停留在如何产生的所有可能的列表了一下。组合只会给我一个字符串集合子集的长度,排列会给出所有可能的排序方法。

我可以在列表中仅使用一个逗号作为遍历切片的所有情况,但我无法使用两个逗号分别为“ab”,“c”,“d”和“a” , “b”, “CD”

我尝试瓦特/片:

test="abcd" 

for x in range(len(test)): 
    print test[:x],test[x:] 
+0

到迭代工具评议,哪一页?我正在浏览这个http://docs.python.org/2/library/itertools。html,但也许这是不正确的搜索通过 –

+3

有2 ^(n-1)的可能性(你错过了[['a','bc','d']'在你的例子中),因为在每个点在字母之间,你可以分割或不分割字符串。 –

回答

15

如何是这样的:

from itertools import combinations 

def all_splits(s): 
    for numsplits in range(len(s)): 
     for c in combinations(range(1,len(s)), numsplits): 
      split = [s[i:j] for i,j in zip((0,)+c, c+(None,))] 
      yield split 

其中:

>>> for x in all_splits("abcd"): 
...  print(x) 
...  
['abcd'] 
['a', 'bcd'] 
['ab', 'cd'] 
['abc', 'd'] 
['a', 'b', 'cd'] 
['a', 'bc', 'd'] 
['ab', 'c', 'd'] 
['a', 'b', 'c', 'd'] 
+1

+1为什么不能你不是简单地“屈服”它,而不是将它存储在“split”中? – thefourtheye

+0

@thefourtheye:只是因为我倾向于一行一行地工作,而且我没有意识到我当时已经够深了。 :^)你是对的,当然,没有必要绑定一个本地的。 – DSM

+0

对我来说这个疯狂多少是在这一行:split = [s [i:j] for zip,((0,)+ c,c +(None,))],但我终于明白了! –

3

使用itertools:

import itertools 
input_str = "abcd" 
for k in range(1,len(input_str)): 
    for subset in itertools.combinations(range(1,len(input_str)), k): 
     s = list(input_str) 
     for i,x in enumerate(subset): s.insert(x+i, ",") 
     print "".join(s) 

给出:

a,bcd 
ab,cd 
abc,d 
a,b,cd 
a,bc,d 
ab,c,d 
a,b,c,d 

另外一个递归版本:

def commatoze(s,p=1): 
    if p == len(s): 
     print s 
     return 
    commatoze(s[:p] + ',' + s[p:], p + 2) 
    commatoze(s, p + 1) 

input_str = "abcd" 
commatoze(input_str) 
+0

更多选项用于生成响应上一个问题的功率集:http://stackoverflow.com/questions/1482308/whats-a-good-way-to-combinate-through-a-set –

15

您当然可以使用itertools这一点,但我觉得它更容易直接写一个递归发生器:

def gen_commas(s): 
    yield s 
    for prefix_len in range(1, len(s)): 
     prefix = s[:prefix_len] 
     for tail in gen_commas(s[prefix_len:]): 
      yield prefix + "," + tail 

然后

print list(gen_commas("abcd")) 

打印

['abcd', 'a,bcd', 'a,b,cd', 'a,b,c,d', 'a,bc,d', 'ab,cd', 'ab,c,d', 'abc,d'] 

我不确定为什么我觉得这更容易。也许只是因为它很容易直接做到这一点;-)

+0

现在尝试在一个非常长的字符串..(我知道,我知道,不要拖拉超人的斗篷..) – DSM

1

你可以解决integer composition problem,并使用作曲来指导在哪里拆分列表。使用一点动态编程就可以很容易地解决整数组合问题。

def composition(n): 
    if n == 1: 
     return [[1]] 
    comp = composition (n - 1) 
    return [x + [1] for x in comp] + [y[:-1] + [y[-1]+1] for y in comp] 

def split(lst, guide): 
    ret = [] 
    total = 0 
    for g in guide: 
     ret.append(lst[total:total+g]) 
     total += g 
    return ret 

lst = list('abcd') 
for guide in composition(len(lst)): 
    print split(lst, guide) 

另一种方式来产生整数组成:

from itertools import groupby 
def composition(n): 
    for i in xrange(2**(n-1)): 
     yield [len(list(group)) for _, group in groupby('{0:0{1}b}'.format(i, n))]