两个列表的组合(不是元素)

时间:2017-03-06 16:38:48

标签: python

我有两个清单:

a = ['a', 'b']
b = [1, 2, 3]

我希望得到列表b的元素与列表a的元素之间产生的组合,但将a的元素作为对(或三元组等)处理,如下例所示提供len(b) ** len(a)个组合数。

c = ["a_1 b_1", "a_1 b_2", "a_1 b_3", "a_2 b_1", "a_2 b_2", "a_2 b_3", "a_3 b_1", "a_3 b_2" "a_3 b_3"]

我尝试使用itertools.product(如here所述),但这只会提供6种可能的组合。

2 个答案:

答案 0 :(得分:14)

您可以使用itertools.product(..),但请指定repeatrepeat=len(a)。所以你可以使用:

from itertools import product

def mul_product(a,b):
    for tup in product(b,repeat=len(a)):
        yield ' '.join('%s_%s'%t for t in zip(a,tup))

product(..)会生成像:

这样的元组
>>> list(product(b,repeat=len(a)))
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

所以这里元组的第一个元素是附加到a_的元素,第二个元素附加到b_。现在我们zip(..)将它们与a列表一起生成:

>>> list(map(lambda bi:list(zip(a,bi)),product(b,repeat=len(a))))
[[('a', 1), ('b', 1)], [('a', 1), ('b', 2)], [('a', 1), ('b', 3)], [('a', 2), ('b', 1)], [('a', 2), ('b', 2)], [('a', 2), ('b', 3)], [('a', 3), ('b', 1)], [('a', 3), ('b', 2)], [('a', 3), ('b', 3)]]

现在只需要格式化('%s_%s'%t)和' '.join(..)将它们组合在一起并yield它们(或者您可以使用列表理解来生成列表)。

您输入样本的结果是:

>>> list(mul_product(a,b))
['a_1 b_1', 'a_1 b_2', 'a_1 b_3', 'a_2 b_1', 'a_2 b_2', 'a_2 b_3', 'a_3 b_1', 'a_3 b_2', 'a_3 b_3']

请注意,这里的元素是懒惰生成的。如果您仅对第一个k感兴趣,或者您不想一次生成所有这些内容,则此功能非常有用。

答案 1 :(得分:4)

您可以使用itertools.product明确创建成对项目,然后使用itertools.product再次对这些对进行操作

import itertools
a = ['a', 'b']
b = [1, 2, 3]
pairs = [list(itertools.product([ai], b)) for ai in a]

pairs将包含可再次输入itertools.product的两个列表。

list(itertools.product(*pairs))

结果是:

[(('a', 1), ('b', 1)),
 (('a', 1), ('b', 2)),
 (('a', 1), ('b', 3)),
 (('a', 2), ('b', 1)),
 (('a', 2), ('b', 2)),
 (('a', 2), ('b', 3)),
 (('a', 3), ('b', 1)),
 (('a', 3), ('b', 2)),
 (('a', 3), ('b', 3))]