Python itertools - 仅创建所有可能产品的子集

时间:2015-11-09 17:07:48

标签: python iteration itertools

我正在编写一个脚本,该脚本使用itertools生成给定参数的所需组合。我在制作适当的套装时遇到了麻烦。但是当某些变量被链接时,即排除某些组合。请考虑以下事项:

import itertools

A = ['a1','a2','a3']
B = ['b1','b2','b3']
C = ['c1','c2']

如果我想生成这些元素的所有可能组合,我可以简单地使用itertools.product()

all_combinations = list(itertools.product(A,B,C))

这给出了预期的

[('a1', 'b1', 'c1'), ('a1', 'b1', 'c2'), ('a1', 'b2', 'c1'), ... 
('a3', 'b2', 'c2'), ('a3', 'b3', 'c1'), ('a3', 'b3', 'c2')]

18种组合(3 * 3 * 2)

但是,我该怎样链接'参数A和B使得每个返回的集合仅包含''' bn'元素?也就是说,我试过了:

ABprecombine = zip(A,B)
limited_combinations = list(itertools.product(ABprecombine,C))

返回

[(('a1', 'b1'), 'c1'), (('a1', 'b1'), 'c2'), (('a2', 'b2'), 'c1'),
 (('a2', 'b2'), 'c2'), (('a3', 'b3'), 'c1'), (('a3', 'b3'), 'c2')]

这是六种(3 * 1 * 2)所需产品,但显然由于我创建它的方式,我现在有一个额外的元组。

当然,我可以生成所有组合,然后过滤掉给定的组合,但是有一种聪明的方式来链接'参数如上?

1 个答案:

答案 0 :(得分:4)

此处,压缩AB是正确的方法。如果你愿意,你可以很容易地扁平化元组:

limited_combinations = [(a, b, c) for ((a, b), c) in itertools.product(zip(A, B), C)]

如果你想更详细地控制产生什么组合,事情会变得更加复杂,直到难以解决像布尔可满足性这样的NP难题。如果发生这种情况,请查看现有的库。