python - 寻找组合的组合

标签 python combinatorics

假设我们有一个列表列表:

list = [[a],[b],[c],[d],[e],[f],[g],[h]]

现在我希望生成 2 x 3 的所有可能组合,因此一种可能的组合是:

[[[a],[b],[c]], [[d],[e],[f]]]

另一个是:

[[[g],[h],[c]], [[d],[e],[f]]]

[[[a],[b],[f]], [[d],[e],[c]]]

顺序在任何级别都不重要。但是,元素不得重复,这意味着以下列表将不正确,不应生成:

[[[a],[b],[f]], [[a],[e],[f]]]

同样

 [[a,b,c], [e,f,c]]   and   [[e,f,c], [a,b,c]]

是同样的事情,并且应该只出现一次。

我已经炸了相当多的神经细胞,但一直无法产生一个有效的解决方案。我正在使用Python来解决这个问题。

最佳答案

您可以使用递归生成器函数:

lst = [['a'],['b'],['c'],['d'],['e'],['f'],['g'],['h']]
x = 3
def combos(lst, n, c = []):
   if sum(map(len, c)) == (l:=len(lst))-(l%x):
      yield c
   else:
      for i in filter(lambda x:not any(x in i for i in c), lst):
         if not c or len(c[-1]) == n:
             yield from combos(lst, n, c+[[i]])
         else:
             yield from combos(lst, n, [*c[:-1], c[-1]+[i]])

result = list(combos(lst, x))
print(result[:10])

输出:

[[['a'], ['b'], ['c']], [['d'], ['e'], ['f']]]
[[['a'], ['b'], ['c']], [['d'], ['e'], ['g']]]
[[['a'], ['b'], ['c']], [['d'], ['e'], ['h']]]
[[['a'], ['b'], ['c']], [['d'], ['f'], ['e']]]
[[['a'], ['b'], ['c']], [['d'], ['f'], ['g']]]
[[['a'], ['b'], ['c']], [['d'], ['f'], ['h']]]
[[['a'], ['b'], ['c']], [['d'], ['g'], ['e']]]
[[['a'], ['b'], ['c']], [['d'], ['g'], ['f']]]
[[['a'], ['b'], ['c']], [['d'], ['g'], ['h']]]
[[['a'], ['b'], ['c']], [['d'], ['h'], ['e']]]
...

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

相关文章:

jQuery html(text) 通过ajax 解析

python - 什么是安装 Python 模块或包?

c++ - 重复组合计数

java - 测试这个的最佳方法是什么? 4位二进制数

algorithm - 计算n位字符串的数量,以使在字符串的每个前缀中,零的数量至少是k的数量的k倍

Python - Flask - 停止页面重新提交发布请求

python - 如何使用 fields_get 方法编辑 View ?

python - 用python替换二维数组的对角线

c - 使用模拟在一手 6 张牌中恰好有一张大牌

sql - 生成SQL中的所有组合