ActiveState Code

Recipe 121294: simple generator for flattening nested containers


this generator flattens nested containers such as

<code> l=( (1,23), [[[[42,(5,23)]]]])</code>

so that

<code> for i in flatten(l): print i</code>

gives you 1,23,42,5,23

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def flatten(*args):
    for arg in args:
            try: 
                for i in arg:
                    for l in flatten(i):
                        yield l

            except TypeError,e: yield arg


#---
# if you dislike the try and exception type of programming (which is
# usually a bit dangerous as it may hide a valid exception), you
# could instead do:

for arg in args: 
    if type(arg) in (type(()),type([])):
        for elem in arg:
            for f in flatten(elem):
                yield f
    else: yield arg

# which is obviously restricted to lists and tuples and does
# not work with user defined containers.
# note that you pass more than one container to flatten and
# all elements of every containers will yielded.
 

Comments

  1. 1. At 6:10 a.m. on 19 aug 2002, Hemanth Sethuram said:

    Checking for other sequence types. You can use the 'types' module to check for other sequence types e.g.

    import types
    sequence_types = \
    [types.ListType,types.TupleType,types.StringTypes,types.SliceType,types.XrangeType,types.BufferType]
    
    for arg in args:
        if type(arg) in sequence_types:
    #rest of the code same as before
    

    -Hemanth (hemanth_sethuram at yahoo dot com)

  2. 2. At 2:59 p.m. on 16 jan 2003, ParzAspen Aspen said:

    This function won't work if a string occurs anywhere within its argument(s). A string's elements are strings, so flatten recurs infinitely if it encounters a string in the structure it is flattening. Having no string element type is one of Python's warts, and the author of this recipie has just stumbled over it.

    >>> for x in flatten(('a','b')): print x
    ...
    Traceback (most recent call last):
      File "", line 1, in ?
      File "", line 5, in flatten
      File "", line 5, in flatten
    [snip]
      File "", line 5, in flatten
    RuntimeError: maximum recursion depth exceeded
    >>>
    

Sign in to comment