多个列表的python组合

标签 python algorithm combinations python-itertools

是否有任何 pythonic 方法来生成多个列表之间的组合? (类似于笛卡尔积,但更复杂)

例子:

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]
# ...
# there are more than 3 lists

预期输出:

1. [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
2. [(1, 4, 8), (2, 5, 7), (3, 6, 9)]
3. [(1, 4, 9), (2, 5, 7), (3, 6, 8)]
4. [(1, 5, 7), (2, 4, 8), (3, 6, 9)]
5. ...

更新:

感谢您的快速回复~!!

澄清问题:

结果都是列表a、b、c的笛卡尔积的不重复组合。

可以通过另一种丑陋的方法来完成:

1) 生成整个笛卡尔积列表

from itertools import product, combinations, chain
t = list(product(a, b, c))

2)使用组合产生所有可能的结果

p = list(combinations(t, 3))

3)过滤重复条件

cnt = len(list(chain(a, b, c)))
f = [x for x in p if len(set(chain(*x))) == cnt]

更新2:

通过丑陋的方法生成的预期结果:

((1, 4, 7), (2, 5, 8), (3, 6, 9))
((1, 4, 7), (2, 5, 9), (3, 6, 8))
((1, 4, 7), (2, 6, 8), (3, 5, 9))
((1, 4, 7), (2, 6, 9), (3, 5, 8))
((1, 4, 8), (2, 5, 7), (3, 6, 9))
((1, 4, 8), (2, 5, 9), (3, 6, 7))
((1, 4, 8), (2, 6, 7), (3, 5, 9))
((1, 4, 8), (2, 6, 9), (3, 5, 7))
((1, 4, 9), (2, 5, 7), (3, 6, 8))
((1, 4, 9), (2, 5, 8), (3, 6, 7))
((1, 4, 9), (2, 6, 7), (3, 5, 8))
((1, 4, 9), (2, 6, 8), (3, 5, 7))
((1, 5, 7), (2, 4, 8), (3, 6, 9))
((1, 5, 7), (2, 4, 9), (3, 6, 8))
((1, 5, 7), (2, 6, 8), (3, 4, 9))
((1, 5, 7), (2, 6, 9), (3, 4, 8))
((1, 5, 8), (2, 4, 7), (3, 6, 9))
((1, 5, 8), (2, 4, 9), (3, 6, 7))
((1, 5, 8), (2, 6, 7), (3, 4, 9))
((1, 5, 8), (2, 6, 9), (3, 4, 7))
((1, 5, 9), (2, 4, 7), (3, 6, 8))
((1, 5, 9), (2, 4, 8), (3, 6, 7))
((1, 5, 9), (2, 6, 7), (3, 4, 8))
((1, 5, 9), (2, 6, 8), (3, 4, 7))
((1, 6, 7), (2, 4, 8), (3, 5, 9))
((1, 6, 7), (2, 4, 9), (3, 5, 8))
((1, 6, 7), (2, 5, 8), (3, 4, 9))
((1, 6, 7), (2, 5, 9), (3, 4, 8))
((1, 6, 8), (2, 4, 7), (3, 5, 9))
((1, 6, 8), (2, 4, 9), (3, 5, 7))
((1, 6, 8), (2, 5, 7), (3, 4, 9))
((1, 6, 8), (2, 5, 9), (3, 4, 7))
((1, 6, 9), (2, 4, 7), (3, 5, 8))
((1, 6, 9), (2, 4, 8), (3, 5, 7))
((1, 6, 9), (2, 5, 7), (3, 4, 8))
((1, 6, 9), (2, 5, 8), (3, 4, 7))

最佳答案

您想要的不是组合,而是排列。 3 个元素有 6 个排列,2 组排列的笛卡尔积有 36。PM 2Ring 最初怀疑你想要所有这 3 个排列,因为你的问题没有说明。如果您问题中的代码产生了所需的输出,则意味着您希望置换 bc 而不是 a。最初,我编写了计算所有 abc 排列的代码。但是,由于 a 不需要置换,我们只需将它包装在一个列表中。这使我们非常接近所需的输出:

import itertools as it

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]

for i in it.product([tuple(a)], it.permutations(b), it.permutations(c)):
    print(i)

输出为以

开头的36行
((1, 2, 3), (4, 5, 6), (7, 8, 9))
((1, 2, 3), (4, 5, 6), (7, 9, 8))
((1, 2, 3), (4, 5, 6), (8, 7, 9))

它已经与您想要的格式几乎相同,但索引已转置,因此 o[x][y] 将匹配您的 o[y][x]所需的输出。我们使用一些 zip magic转置它们。另外,此函数现在适用于任意数量的参数:

import itertools as it

a = [1, 2, 3]
b = [4, 5, 6]
c = [7, 8, 9]

def funnyperms(first, *rest):
    for i in it.product([first], *(it.permutations(j) for j in rest)):
        yield tuple(zip(*i))

for i in funnyperms(a, b, c):
    print(i)

输出是

((1, 4, 7), (2, 5, 8), (3, 6, 9))
((1, 4, 7), (2, 5, 9), (3, 6, 8))
((1, 4, 8), (2, 5, 7), (3, 6, 9))
((1, 4, 8), (2, 5, 9), (3, 6, 7))
((1, 4, 9), (2, 5, 7), (3, 6, 8))
((1, 4, 9), (2, 5, 8), (3, 6, 7))
((1, 4, 7), (2, 6, 8), (3, 5, 9))
((1, 4, 7), (2, 6, 9), (3, 5, 8))
((1, 4, 8), (2, 6, 7), (3, 5, 9))
((1, 4, 8), (2, 6, 9), (3, 5, 7))
((1, 4, 9), (2, 6, 7), (3, 5, 8))
((1, 4, 9), (2, 6, 8), (3, 5, 7))
((1, 5, 7), (2, 4, 8), (3, 6, 9))
((1, 5, 7), (2, 4, 9), (3, 6, 8))
((1, 5, 8), (2, 4, 7), (3, 6, 9))
((1, 5, 8), (2, 4, 9), (3, 6, 7))
((1, 5, 9), (2, 4, 7), (3, 6, 8))
((1, 5, 9), (2, 4, 8), (3, 6, 7))
((1, 5, 7), (2, 6, 8), (3, 4, 9))
((1, 5, 7), (2, 6, 9), (3, 4, 8))
((1, 5, 8), (2, 6, 7), (3, 4, 9))
((1, 5, 8), (2, 6, 9), (3, 4, 7))
((1, 5, 9), (2, 6, 7), (3, 4, 8))
((1, 5, 9), (2, 6, 8), (3, 4, 7))
((1, 6, 7), (2, 4, 8), (3, 5, 9))
((1, 6, 7), (2, 4, 9), (3, 5, 8))
((1, 6, 8), (2, 4, 7), (3, 5, 9))
((1, 6, 8), (2, 4, 9), (3, 5, 7))
((1, 6, 9), (2, 4, 7), (3, 5, 8))
((1, 6, 9), (2, 4, 8), (3, 5, 7))
((1, 6, 7), (2, 5, 8), (3, 4, 9))
((1, 6, 7), (2, 5, 9), (3, 4, 8))
((1, 6, 8), (2, 5, 7), (3, 4, 9))
((1, 6, 8), (2, 5, 9), (3, 4, 7))
((1, 6, 9), (2, 5, 7), (3, 4, 8))
((1, 6, 9), (2, 5, 8), (3, 4, 7))

将这些存储到一个集合中并与您的方法产生的值进行比较,证明它们具有相同的输出:

print(set(funnyperms(a, b, c)) == set(f))

打印True,Q.E.D.

关于多个列表的python组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45308238/

相关文章:

python - 'as' 运算符是做什么的?

python - 模块未找到错误: No module named 'dask.dataframe' ; 'dask' is not a package

c - 虽然循环没有按预期工作以将各种情况作为终端的输入)

php - 类似于 SimpleHTTPServer 但支持 PHP 的简单 python 服务器?

python - Django + Mezzanine 中的翻译问题

python - 以子列表的形式获取列表的所有可能组合

Python - 有效地从两个字典中获取所有可能的组合

r - 如何将我现有的 R 代码从随机样本的输出更改为所有可能结果的列表?

c# - 如何在 C# 中解决 Randomize in place 算法?

algorithm - 最长公共(public)子串