Welcome, guest | Sign In | My Account | Store | Cart

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, 26 lines
 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.
 

2 comments

Hemanth Sethuram 21 years, 8 months ago  # | flag

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)

ParzAspen Aspen 21 years, 3 months ago  # | flag

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
>>>
Created by H. Krekel on Wed, 17 Apr 2002 (PSF)
Python recipes (4591)
H. Krekel's recipes (4)

Required Modules

  • (none specified)

Other Information and Tasks