subtuples for a tuple

algorithm, python, python-3.x

Solution

Handle base case - when `segment` is empty:

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

Example usage:

>>> 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'))

Problem

I wish to yield the following: ``` (('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'),) ``` when calling `sub_combinations(('A', 'B', 'C', 'D'))` Here's my attempt but it doesn't work: ``` def sub_combinations(segment): for i in range(1, len(segment)): for j in sub_combinations(segment[i:]): yield segment[:i]+j yield segment ``` but I think I'm on the right track. Additionally, I'd like to have a second argument called limit which limits the size of the sub tuples, for example `sub_combinations(('A', 'B', 'C', 'D'), 2)` would give: ``` (('A',), ('B',), ('C',), ('D',)) (('A',), ('B',), ('C','D')) (('A',), ('B','C'), ('D',)) (('A','B'), ('C',), ('D',)) (('A','B'), ('C','D')) ``` I'm using python 3.

Original source