如何在所有可能的情况下拆分列表?

时间:2017-04-16 17:02:24

标签: python python-2.7

对于像

这样的列表
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))

有没有人有一个好方法?

2 个答案:

答案 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}]不在输出中。这应该足以让你开始。