2016-04-08 77 views
1

[0.0,1.0,2.0,3.0,4.0]将列表分成两个非空列表的所有方法

我有5个数字和左右两组。 每个号码有两个选择 - 它可以向左或向右。 我需要一个列表,其中包含列表[0,1,2,3,4]的所有分区成两个非空的部分。例如:[([0],[1,2,3,4]),([0,1],[2,3,4]),...,]

请注意, (2^5 -2)/ 2划分的顺序无关紧要,我不想重复。这意味着我想是这样的(如果我的名单是[1,2,3,4]):

[] [1, 2, 3, 4] 
[1] [2, 3, 4] 
[2] [1, 3, 4] 
[1, 2] [3, 4] 
[3] [1, 2, 4] 
[1, 3] [2, 4] 
[2, 3] [1, 4] 
[1, 2, 3] [4] 
[4] [1, 2, 3] 
[1, 4] [2, 3] 
[2, 4] [1, 3] 
[1, 2, 4] [3] 
[3, 4] [1, 2] 
[1, 3, 4] [2] 
[2, 3, 4] [1] 
[1, 2, 3, 4] [] 

我已经研究过所有的迭代工具功能,没有似乎工作。


编辑: 的名单[我为我的range(16)],其中有16个元素,如果我这样做,这是我所看到的:

n = len(l)//2 + 1 
>>> xs = list(chain(*[combinations(l, i) for i in range(1, n)])) 
>>> pairs = [(list(x), list(set(l) - set(x))) for x in xs] 
>>> print len(pairs) 
    39202 
>>> (2**16-2)/2 
    32767 

事实上,它不适用于包含6个元素的列表。我不明白为什么......

所有偶数长度列表都会出现问题。例如,当我尝试一个长度2列表,我得到:

[([0.0],[1.0]),([1.0],[0.0])]

回答

3

的东西是有在itertools,也许你只是没有看到正确的地方。

这里是格兰codez:

from collections import OrderedDict 
from itertools import chain, combinations 

def partition(L): 
    n = len(L)//2 + 1 
    xs = chain(*[combinations(L, i) for i in range(1, n)]) 
    pairs = (tuple(sorted([x, tuple(set(L) - set(x))])) for x in xs) 
    return OrderedDict.fromkeys(pairs).keys() 

输出:

>>> for pair in partition([1,2,3,4]): 
...  left, right = map(list, sorted(pair, key=len)) 
...  print left, right 
... 
[1] [2, 3, 4] 
[2] [1, 3, 4] 
[3] [1, 2, 4] 
[4] [1, 2, 3] 
[1, 2] [3, 4] 
[1, 3] [2, 4] 
[1, 4] [2, 3] 
+1

等待,这是我得到:[(0,),(1,),(2),(3 (0,1),(0,2),(0,3),(0,4),(1,2),(1,3),(1,4), (2,3),(2,4),(3,4)]。对于每个分区,我需要将列表L中的所有元素分组到左边或右边两个列表中的一个。我想要所有这样的分区。 – Jobs

+1

赞:[(左,右),(左,右),(左,右)...... [15元素分成两个非空组。]] – Jobs

+0

编辑。我曾以为你可以自己找出其他的......; – wim