简体   繁体   English

使用itertools从列表进行组合

[英]Making Combination from lists using itertools

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

How would I go about using the combination function from itertools properly to use list a one time, b 2 times without replacement, c 2 times without replacement, and d and e one time each? 我将如何正确使用itertools中的组合功能来使用列表一次,b两次不替换,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]]]

It seems like you are looking for a combination of combinations and product : Use combinations to get the possible combinations without replacement for the repeated lists, then use product to combine all those combinations. 似乎您正在寻找combinationsproductcombinations :使用combinations来获得可能的组合而不替换重复的列表,然后使用product来组合所有这些组合。 You can put the lists and counts in two lists, zip those lists, and use a generator expression to get all the combinations. 您可以将列表和计数放在两个列表中,将这些列表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)))

For this example, the combs generator has 48 elements, among others: 对于此示例, 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],))]

If you want flattened lists , just chain them: 如果您想要扁平化的列表 ,只需将它们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]]]

Updated given clarification of expected output : 更新了给定的预期产出说明

You want itertools.product : 您想要itertools.product

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

Which will pick one element from each of its arguments on each iteration, cycling the rightmost element the fastest, leftmost slowest. 它将在每次迭代时从其每个参数中选择一个元素,以最快,最慢的速度循环最右边的元素。

You can use extended argument unpacking to express the repetition of certain arguments a little more obviously in Python 3: 您可以使用扩展参数解压缩来表达某些参数的重复,这在Python 3中更为明显:

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

Or use tobias_k's solution for more general repetition of sequences (that will also work on Py2). 或使用tobias_k解决方案对序列进行更一般的重复(这也适用于Py2)。

What your are trying to achieve is the Cartesian product of input iterables and not the combinations of the item present in the list. 您要实现的是Cartesian product of input iterables项的Cartesian product of input iterables而不是列表中存在的项的组合。 Hence you have to use itertools.product() instead. 因此,您必须改为使用itertools.product()

In case repetition is allowed among the lists which used more than once, answer is simple: 如果允许在使用多次的列表中重复,答案很简单:

>>> 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)]

But in case repetition is not allowed within the same lists, it will become little nasty and you need to combine the above answer with combinations() and chain() (same as mentioned by tobias_k ). 但是,如果在同一列表中repetition is not allowed ,它将变得有点讨厌,您需要将上述答案与Combines combinations()chain() combinations()tobias_k相同)。 This code will give the list of all combinations : 此代码将列出所有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]]

However, in case you need permutations instead of combinations, you have to update the above code with permutations() : 但是,如果您需要置换而不是组合,则必须使用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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM