对于像
这样的列表a = [1,2,3,4,5]
我想在结果中得到它所有的两个元素子集,如:
[((1, 2), (3, 4)),
((1, 2), (3, 5)),
((1, 2), (4, 5)),
((1, 3), (2, 4)),
((1, 3), (2, 5)),
((1, 3), (4, 5)),
((1, 4), (2, 3)),
((1, 4), (2, 5)),
((1, 4), (3, 5)),
((1, 5), (2, 3)),
((1, 5), (2, 4)),
((1, 5), (3, 4))]
我写了一个愚蠢的代码,如:
b=[]
for i in combinations(a,2):
for j in combinations(a,2):
if(set(i).intersection(j)==set()):
b.append((i,j))
有没有人有一个好方法?
答案 0 :(得分:1)
@insomnia以下代码用于生成排列,我认为可以很容易地自定义它以适合您的情况:
import itertools
a = [1,2,3,4,5]
result = []
for combo in itertools.permutations(a, 2):
result.append(combo)
print(len(result))
答案 1 :(得分:0)
为了使这种算法更好,制作一个递归函数,系统地减少问题,而不是寻找交叉点。
递归缩减步骤基本上是“将k元素从池中取出然后拆分池的余数”。像这样:
from itertools import combinations
from pprint import pprint
def split(s, k=2): # type: (s: set) -> Iterable[List[tuple]]
if len(s) <= k:
yield []
for thispair in combinations(s, k):
remainder = s.difference(thispair)
for otherpairs in split(remainder, k):
yield [thispair] + otherpairs
pprint(list(split({1, 2, 3, 4, 5})))
需要一些额外的逻辑来确保不会探索重复的搜索路径,以便[{1, 2}, {3, 4}]
和[{3, 4}, {1, 2}]
不在输出中。这应该足以让你开始。