2017-05-01 83 views
1

什麼是生成列表的所有組合的最佳方式,其中每個組合都包含列表中的每個項目以及可以組合其他項目的位置。生成列表的所有已排序組合,其中每個組合都包含所有項目

例如,對於一個列表['a','b','c'],我喜歡生成:

['a','b','c'] 
['ab','c'] 
['a','bc'] 
['abc'] 

我覺得這是一個有點類似:Python: Generating all ordered combinations of a list。但是這隻關心切片。我想要從列表中獲取每個項目的所有組合。是否有itertools的內置函數可用於生成答案?

該列表也可能是數字,可能有重複的值。例如:[1,2,1]應該產生:

[1,2,1] 
[12,1] 
[1,21] 
[121] 

我可以嘗試從鏈接中使用的代碼,但不是生成項目的組合,我將生成的列表中的指數組合的基礎。在我以0開頭的所有組合的情況下,查找下一個項目並查找以該項目開頭的所有組合等等。我不認爲這將是有效的。

回答

1

您可以將字符串中的兩個相鄰字符視爲「分隔」或「連接」。使用itertools.product()您可以生成的所有組合分離/兩個字符之間串接,然後使用一個簡單的函數從該信息生成的字符串列表:

import itertools 

l = ['a','b','c'] 

def generate_combination(source, comb): 
    res = [] 
    for x, action in zip(source,comb + (0,)): 
     res.append(x) 
     if action == 0: 
      yield "".join(res) 
      res = [] 

print [list(generate_combination(l,c)) 
     for c in itertools.product((0,1), repeat=len(l)-1)] 

但除非你把它們轉換成這不換號工作串首先。

+0

這似乎很好地工作。試圖看看它是如何工作的。 – user1179317

+0

我剛剛瞭解你的發電機功能,它非常酷。感謝你的回答。 – user1179317

1

下面是使@acidtobi answer intchar.isdigit()幫助下工作的附加代碼。

final = [list(generate_combination(l,c)) 
     for c in itertools.product((0,1), repeat=len(l)-1)] 

print [[int(i) if i.isdigit() else i for i in alist ] for alist in final] 

所以對於l = [ 1,2,3],它會顯示

>>> 
[[1, 2, 3], [1, 23], [12, 3], [123]] 

而對於l = ['a','b','c']

>>> 
[['a', 'b', 'c'], ['a', 'bc'], ['ab', 'c'], ['abc']] 
1
import numpy as np 
l = ['a','b','c','d'] 
#l = [0,1,2,3] 
d = np.arange(2**(len(l)-1)) 
#create a separator array for all possible combinations 
sep = np.where((d[:,None] & (1 << np.arange(len(l))[::-1])) > 0, ',','') 
#merge the separator to the strings 
merged = np.core.defchararray.add(sep,np.asarray(l,dtype=str)).tolist() 
#reformat and split 
[''.join(e).split(',') for e in merged] 

#works for any characters 
[['abcd'], 
['abc', 'd'], 
['ab', 'cd'], 
['ab', 'c', 'd'], 
['a', 'bcd'], 
['a', 'bc', 'd'], 
['a', 'b', 'cd'], 
['a', 'b', 'c', 'd']] 

Out[128]: 
[['0123'], 
['012', '3'], 
['01', '23'], 
['01', '2', '3'], 
['0', '123'], 
['0', '12', '3'], 
['0', '1', '23'], 
['0', '1', '2', '3']]