2016-09-15 12 views
2
import itertools 
a = [[2, 3], [3, 4]] 
b = [[5, 6], [7, 8], [9, 10]] 
c = [[11, 12], [13, 14]] 
d = [[15, 16], [17, 18]] 
e = [[12,16],[13,17],[14,18],[15,19]] 

q=[] 
q=list(itertools.combinations((a, b, b,c, c, d,e),7) 
print q 

如何使用itertools的組合函數正確使用列表一次,b 2次不更換,c 2次不更換,以及d和e每次一次?使用itertools從列表中進行組合

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

是兩個從'平b'是否有更換? –

+1

我不確定我是否理解你在這裏想要的東西(你能給出第一個例子的輸出還是要確定的東西?),但是如果你將'itertools.combinations'包裝在'list'中以獲得相當數量的輸入,你幾乎保證吹噓你的記憶。輸出的數量大致增長爲「O(n!)」(階乘增長);您通常需要逐個迭代組合,而不是一次全部存儲它們。 – ShadowRanger

+0

沒有替換, –

回答

2

好像你正在尋找combinationsproduct組合:使用combinations,以獲得可能的組合,而無需更換爲重複列表,然後使用product所有這些組合相結合。您可以將列表和計數放在兩個列表中,zip這些列表中,並使用生成器表達式來獲取所有組合。

from itertools import product, combinations, chain 
lists = [a,b,c,d,e] 
counts = [1,2,2,1,1] 
combs = product(*(combinations(l, c) for l, c in zip(lists, counts))) 

在這個例子中,combs發電機有48元,其中包括:

[(([2, 3],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([2, 3],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([17, 18],), ([15, 19],)), 
(([2, 3],), ([5, 6], [9, 10]),([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([3, 4],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([15, 16],), ([12, 16],)), 
... 
(([3, 4],), ([5, 6], [7, 8]), ([11, 12], [13, 14]), ([17, 18],), ([15, 19],)), 
... 
(([3, 4],), ([7, 8], [9, 10]),([11, 12], [13, 14]), ([17, 18],), ([15, 19],))] 

如果你想flattened lists,只是chain他們:

>>> combs = (list(chain(*p)) for p in product(*(combinations(l, c) for l, c in zip(lists, counts)))) 
>>> list(combs) 
[[[2, 3], [5, 6], [7, 8], [11, 12], [13, 14], [15, 16], [12, 16]], 
... 
[[3, 4], [7, 8], [9, 10], [11, 12], [13, 14], [17, 18], [15, 19]]] 
+0

謝謝你這是真棒 –

1

更新給出明確預期的輸出的:

You want itertools.product

itertools.product(a, b, b, c, c, c, c, d, e) 

這將挑選在每次迭代從每個參數一個元素,騎自行車最右邊的元素最快,最左邊最慢。

您可以使用擴展參數拆包多一點顯然表達的某些參數的重複在Python 3:

itertools.product(a, *[b]*2, *[c]*4, d, e) 

或者使用tobias_k's solution爲序列的更普遍的重複(也將在的Py2工作)。

+1

但是,這不會從b中得出一個,2個等等,但是隻有9個從一起。 –

+1

@tobias_k:我在OP澄清確切用法之前回答。將解決。 – ShadowRanger

1

什麼你正在努力實現是Cartesian product of input iterables而不是列表中的項目組合。因此,您必須改用itertools.product()

如果重複允許其使用一次以上列表中,答案很簡單:

>>> import itertools 
>>> a = [1,2] 
>>> b = [3,4] 
>>> [i for i in itertools.product(a, b, b)] 
[(1, 3, 3), (1, 3, 4), (1, 4, 3), (1, 4, 4), (2, 3, 3), (2, 3, 4), (2, 4, 3), (2, 4, 4)] 

但在同一列表中的情況下repetition is not allowed,它會變得有點討厭,你需要以上組合用combinations()chain()(與tobias_k提到的相同)回答。這個代碼將會給所有combinations名單:

>>> from itertools import chain, product, combinations 
>>> lists, counts = [a, b], [1, 2] # to track that a is to be used once, and b twice 
>>> list(list(chain(*p)) for p in product(*(combinations(l, c) for l, c in zip(lists, counts)))) 
[[1, 3, 4], [2, 3, 4]] 

但是,如果你需要的排列,而不是組合,你必須更新permutations()上面的代碼:

>>> from itertools import chain, product, permutations 
>>> list(list(chain(*p)) for p in product(*(permutations(l, c) for l, c in zip(lists, counts)))) 
[[1, 3, 4], [1, 4, 3], [2, 3, 4], [2, 4, 3]] 
+1

不完全清楚這個問題,但我認爲那麼預期輸出的最後一行應該包含'[13,14],[11,12]'而不是'[11,12],[ 13,14]'。 –

+1

@tobias_k看他的樣本輸出,我相信他需要列表的笛卡爾積。用簡單的例子更新答案。我同意你的觀點,OP所提供的輸入參數太龐大,並且不清楚他的意圖。更簡單的例子將有所幫助 –

+0

訂單無關緊要 –