2017-08-01 59 views
0

我想知道是否有人知道一個python函數,它返回的是不重複的列組合。例如獲取唯一列的組合

a= [[1,2], 
    [3,4]] 
# 1,4 is allowed since not the same column. 
# 2,3 is allowed since not the same column. 
# 1,3 is not allowed since its the same column. 
# 2,4 is not allowed since its the same column. 

即使它的自定義函數您已經使我想看到它,並理解它背後的邏輯。

另外如果可能的話,我希望模塊中的函數默認可以在python中使用,所以不要像numpy那樣需要通過pip手動安裝的地方。

謝謝:)

+0

好像你只需要一種組合。爲此,您可以生成隨機索引並將其拉出。例如'a [0] [random(2)],a [1] [random(2)]' –

+1

什麼是輸入? – Haranadh

+0

我的實際輸入是一個方形矩陣mat = [[1,2,3],[4,5,6],[7,8,9]]。 – pyCharmer

回答

1

您可以使用itertools.product和使用enumerate生成列索引後排除在同一列項:

from itertools import product 

def prod(*args): 
    for (i, x), (j, y) in product(*map(enumerate, args)): 
     if i != j: 
     yield (x, y) 

a= [[1,2], 
    [3,4]] 
print(list(prod(*a))) 
# [(1, 4), (2, 3)] 

a= [[1,2,3], 
    [4,5,6]] 
print(list(prod(*a))) 
# [(1, 5), (1, 6), (2, 4), (2, 6), (3, 4), (3, 5)] 

可以概括這個多行和列通過檢查,沒有列在每個組合中重複:

from itertools import product 

def prod(*args): 
    for items in product(*map(enumerate, args)): 
     if len({i for i, _ in items}) == len(items): 
     yield tuple(x for _, x in items) 
+0

您的代碼適用於我的示例,但是當我將示例中的輸入更改爲方形矩陣時,它會失敗。例如a = [[1,2,3],[4,5,6],[7,8,9]]不能擴展它。 – pyCharmer

+0

@pyCharmer更新了我的回答 –

+0

該死的,那裏有一些漂亮的代碼。需要解決這個問題,這樣我才能理解。 – pyCharmer

0

對於較大的正方形矩陣,可以使用colu排列MNS:

from itertools import * 

b = [ 
     [1,2,3], 
     [4,5,6], 
     [7,8,9], 
    ] 


def combs(mat=b): 
    ncols = len(b[0]) 
    yield from ([mat[i][j] for i, j in inds] 
      for inds in map(enumerate, 
       permutations(range(ncols)))) 

# In [86]: list(q.combs()) 
# Out[86]: [[1, 5, 9], [1, 6, 8], [2, 4, 9], [2, 6, 7], [3, 4, 8], [3, 5, 7]] 

關於最後一行:給予N x N矩陣,恰好有N!的方式來挑選,從各行的元素而沒有選擇兩個或兩個以上的任一列:您在第一行中有N選擇,第二,等等。因此,滿足您的要求的每種組合都被置換爲一個排列組合。 map(enumerate, permutations(range(ncols)))給出了所有有效索引的列表。對於給定索引inds,[mat[i][j] for i, j in inds]給出與該索引對應的列表。

+0

爲什麼醜陋'從itertools導入*'雖然? –

+0

不確定爲什麼它很醜,但是的確如此,你只需要'排列'。 –

+0

我收到來自行的良率的語法錯誤。我不這樣說。你也可以用簡單的方式解釋這條線。 – pyCharmer