[Tutor] flatten a tuple

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Wed, 18 Apr 2001 14:51:37 -0700 (PDT)


On Wed, 18 Apr 2001, Sean 'Shaleh' Perry wrote:

> So I have a tuple:
> 
> ((0, 1, 2), (3,4,5), (6,7,8))
> 
> and I want to get:
> 
> (6,7,8,3,4,5,0,1,2)
> 
> i.e. reverse the container, then get the contents in order.

Reversal isn't too bad; I think that flattening is the more interesting
problem.  One way to do this flattening is with a recursive definition:

To flatten a thing:

    1. Trying to flatten a non-tuple should return that thing in a flat
       tuple.  For example, flatten(42) should give us the tuple
       (42,).

    If we're at this point, the thing must be a tuple:

    2. If the tuple's empty, let's return it without any changes.  That
       is, flatten(()) should return ().

    3. Otherwise, let's flatten the first element of the tuple, and
       concatenate it with the flattening of the rest of the tuple.  What
       we get back should be altogether flattened.

###
>>> def isTuple(x): return type(x) == types.TupleType
... 
>>> def flatten(T):
...     if not isTuple(T): return (T,)
...     elif len(T) == 0: return ()
...     else: return flatten(T[0]) + flatten(T[1:]) 
...
>>> flatten( ((0, 1, 2), (3, 4, 5), (6, 7, 8)) )
(0, 1, 2, 3, 4, 5, 6, 7, 8)
###

What's nice is that the flattening is "deep", that is, it can handle any
amount of nesting:

>>> flatten( ( ((0,), (1, 2)), (3, (((4,))), 5), (6, 7, 8) ) )
(0, 1, 2, 3, 4, 5, 6, 7, 8)


Hope this helps!