返回列表的子组合

时间:2018-12-17 08:52:15

标签: python python-3.x

我有一个函数,可以返回列表中的所有组合:

def sub_combinations(segment):
  if len(segment) == 1:
    yield (segment,)
  else:
    for x, j in enumerate(sub_combinations(segment[1:])):
      yield ((segment[0],),)+j
      for k in range(len(j)):
         yield (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:])

但是如何获取它只返回子组合:

((1,), (2,), (3,), (4,))
((1, 2), (3,), (4,))
((1, 3), (2,), (4,))
((1, 4), (2,), (3,))
((1,), (2, 3), (4,))
((1, 2, 3), (4,))
((1, 4), (2, 3))
((1,), (2, 4), (3,))
((1, 2, 4), (3,))
((1, 3), (2, 4))
((1,), (2,), (3, 4))
((1, 2), (3, 4))
((1, 3, 4), (2,))
((1,), (2, 3, 4))

代替:

((1,), (2,), (3,), (4,))
((1, 2), (3,), (4,))
((1, 3), (2,), (4,))
((1, 4), (2,), (3,))
((1,), (2, 3), (4,))
((1, 2, 3), (4,))
((1, 4), (2, 3))
((1,), (2, 4), (3,))
((1, 2, 4), (3,))
((1, 3), (2, 4))
((1,), (2,), (3, 4))
((1, 2), (3, 4))
((1, 3, 4), (2,))
((1,), (2, 3, 4))
((1, 2, 3, 4),)  # remove this

通过以下方式调用时:

sub_combinations((1,2,3,4))

这是我的无效尝试:

def sub_combinations(segment, d=0):
  if len(segment) == 1:
    yield (segment,)
  else:
    for x, j in enumerate(sub_combinations(segment[1:]), d+1):
      yield ((segment[0],),)+j
      for k in range(len(j)):
         r = (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:])
         if d == 0 and r == (segment,): continue
         yield r

1 个答案:

答案 0 :(得分:2)

我认为您应该分为2个功能,每个功能都有其自己的功能。第一个只是按照您的实现创建组合,第二个只是包装它,并过滤不需要的细分。

类似:

from itertools import filterfalse

def get_combinations(segment):
    pass # your implementation


def get_sub_combinations(segment, filter_func=lambda x: x == segment):
    yield from filterfalse(filter_func, get_combinations(segment))