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次无需替换,d和e各使用一次?
[[[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]]]
答案 0 :(得分:2)
您好像正在寻找combinations
和product
的组合:使用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]]]
答案 1 :(得分:1)
更新了预期输出的说明:
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)。
答案 2 :(得分: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()
结合起来(与{{3}提到的相同) })。此代码将提供所有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]]
但是,如果您需要排列而不是组合,则必须使用tobias_k更新上述代码:
>>> 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]]