元组的子元素

时间:2014-01-27 15:27:11

标签: python algorithm python-3.x

我希望得到以下结论:

(('A',), ('B',), ('C',), ('D',))
(('A',), ('B',), ('C','D'))
(('A',), ('B','C'), ('D',))
(('A',), ('B','C','D'))
(('A','B'), ('C',), ('D',))
(('A','B'), ('C','D'))
(('A','B','C'), ('D',))
(('A','B','C','D'),)

致电sub_combinations(('A', 'B', 'C', 'D'))

这是我的尝试,但它不起作用:

def sub_combinations(segment):
   for i in range(1, len(segment)):
      for j in sub_combinations(segment[i:]):
         yield segment[:i]+j 
      yield segment 

但我认为我走在正确的轨道上。

此外,我想要一个名为limit的第二个参数来限制子元组的大小,例如sub_combinations(('A', 'B', 'C', 'D'), 2)会给出:

(('A',), ('B',), ('C',), ('D',))
(('A',), ('B',), ('C','D'))
(('A',), ('B','C'), ('D',))
(('A','B'), ('C',), ('D',))
(('A','B'), ('C','D'))

我正在使用python 3。

2 个答案:

答案 0 :(得分:7)

处理基本案例 - 当segment为空时:

def sub_combinations(segment, size=0):
    if segment == ():
        yield ()
        return
    stop = min(size or len(segment), len(segment))
    for i in range(1, stop + 1):
        for j in sub_combinations(segment[i:], size):
            yield (segment[:i],) + j

使用示例:

>>> for x in sub_combinations(('A', 'B', 'C', 'D')):
...     print(x)
...
(('A',), ('B',), ('C',), ('D',))
(('A',), ('B',), ('C', 'D'))
(('A',), ('B', 'C'), ('D',))
(('A',), ('B', 'C', 'D'))
(('A', 'B'), ('C',), ('D',))
(('A', 'B'), ('C', 'D'))
(('A', 'B', 'C'), ('D',))
(('A', 'B', 'C', 'D'),)

>>> for x in sub_combinations(('A', 'B', 'C', 'D'), 2):
...     print(x)
...
(('A',), ('B',), ('C',), ('D',))
(('A',), ('B',), ('C', 'D'))
(('A',), ('B', 'C'), ('D',))
(('A', 'B'), ('C',), ('D',))
(('A', 'B'), ('C', 'D'))

答案 1 :(得分:3)

如果你也可以使用列表而不是元组(或者不怕以后转换它们),你可以使用它:

def subtuples(t):
  for i in range(1<< (len(t)-1)):
    result = [ [ t[0] ] ]
    for j in range(len(t)-1):
      if (1<<j) & i:
        result[-1].append(t[j+1])
      else:
        result.append([ t[j+1] ])
    yield result

for x in subtuples(('a', 'b', 'c', 'd')):
  print(x)