2016-04-22 129 views
3

我有一個非常簡單的組合問題。我有兩個數組(a和b)。數組a表示數組b中的三個插槽中的一個可以採用的所有值。數組b中的每個插槽可以具有1到5之間的值。其中的一個例子是[1,4,5]。我想用所有可能的組合生成一個數組(c)。我喜歡擴展更大陣列的基本示例。[Python]:生成和排列所有可能的組合

輸入:

a = [1, 2, 3, 4, 5] 
b = [1, 2, 3] 

輸出:

c = [[1, 1, 1], [1, 1, 2],[1, 1, 3], [1, 1, 4], [1, 1, 5], 
    [1, 2, 1], [1, 2, 2],[1, 2, 3], [1, 2, 4], [1, 2, 5], 
    [1, 3, 1], [1, 3, 2],[1, 3, 3], [1, 3, 4], [1, 3, 5], 
    [1, 4, 1], [1, 4, 2],[1, 4, 3], [1, 4, 4], [1, 4, 5], 
    [1, 5, 1], [1, 5, 2],[1, 5, 3], [1, 5, 4], [1, 5, 5], 
    [2, 1, 1], [2, 1, 2],[2, 1, 3], [2, 1, 4], [2, 1, 5], 
    [2, 2, 1], [2, 2, 2],[2, 2, 3], [2, 2, 4], [2, 2, 5], 
    [2, 3, 1], [2, 3, 2],[2, 3, 3], [2, 3, 4], [2, 3, 5], 
    [2, 4, 1], [2, 4, 2],[2, 4, 3], [2, 4, 4], [2, 4, 5], 
    [2, 5, 1], [2, 5, 2],[2, 5, 3], [2, 5, 4], [2, 5, 5], 
    [3, 1, 1], [3, 1, 2],[3, 1, 3], [3, 1, 4], [3, 1, 5], 
    [3, 2, 1], [3, 2, 2],[3, 2, 3], [3, 2, 4], [3, 2, 5], 
    [3, 3, 1], [3, 3, 2],[3, 3, 3], [3, 3, 4], [3, 3, 5], 
    [3, 4, 1], [3, 4, 2],[3, 4, 3], [3, 4, 4], [3, 4, 5], 
    [3, 5, 1], [3, 5, 2],[3, 5, 3], [3, 5, 4], [3, 5, 5], 
    [4, 1, 1], [4, 1, 2],[4, 1, 3], [4, 1, 4], [4, 1, 5], 
    [4, 2, 1], [4, 2, 2],[4, 2, 3], [4, 2, 4], [4, 2, 5], 
    [4, 3, 1], [4, 3, 2],[4, 3, 3], [4, 3, 4], [4, 3, 5], 
    [4, 4, 1], [4, 4, 2],[4, 4, 3], [4, 4, 4], [4, 4, 5], 
    [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5], 
    [5, 1, 1], [5, 1, 2],[5, 1, 3], [5, 1, 4], [5, 1, 5], 
    [5, 2, 1], [5, 2, 2],[5, 2, 3], [5, 2, 4], [5, 2, 5], 
    [5, 3, 1], [5, 3, 2],[5, 3, 3], [5, 3, 4], [5, 3, 5], 
    [5, 4, 1], [5, 4, 2],[5, 4, 3], [5, 4, 4], [5, 4, 5], 
    [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5]] 

解決以上問題:

d = [] 
for i in range(len(a)): 
    for j in range(len(a)): 
     for k in range(len(a)): 
      e = [] 
      e.append(i+1) 
      e.append(j+1) 
      e.append(k+1) 
      d.append(e) 

我正在尋找一種更通用的方法。一個可以容納更大的數組(見下面)而不需要使用嵌套for循環結構。我搜索了一個可比較的例子,但無法在stackoverflow上找到它。

輸入:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 
+1

看看python [itertools](https://docs.python.org/2/library/itertools.html)。組合方法可以做我認爲你正在尋找的東西。 – Jggrnaut

+2

從你的描述來看,我也不認爲你需要一個'b'數組,只是一個整數值來指定數組的長度 – wilkesybear

+0

當我對一系列公差變量進行MonteCarlo模擬時,我有類似的問題,但是我發現生成一個所有可能組合的數組是無意義的,當它非常容易時(請參閱您自己的代碼)即時生成這些組合。 – roadrunner66

回答

4

您正在尋找itertools.product()

a = [1, 2, 3, 4, 5] 
b = 3 # Actually, you just need the length of the array, values do not matter 

c = itertools.product(a, repeat=b) 

注意它返回一個迭代器,則可能需要將其強制轉換使用list()但要注意這可能需要永遠和高消耗內存,如果規模增長。

1

在一般情況下,您當然應該使用itertools模塊,在此特定情況下itertools.product,如其他答案中所述。

如果你想自己實現這個功能,你可以使用遞歸使它適用於任何數組大小。此外,您應該使其成爲發電機功能(使用yield而不是return),因爲結果可能會相當長。你可以嘗試這樣的:

def combinations(lst, num): 
    if num > 0: 
     for x in lst: 
      for comb in combinations(lst, num - 1): 
       yield [x] + comb 
    else: 
     yield [] 
相關問題