list of lists of lists ....

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Fri Jul 28 15:01:29 EDT 2006


You can use this, fast, gives a tuple:

from Tkinter import _flatten as flatten

-----------------------

The xflatten/flatten version I sometimes use, maybe I can put something
similar in the cookbook, but it can be improved a lot (and isrecursive
is too much fragile):

from pprint import isrecursive

def xflatten(seq, tuplestoo=True, safe=True):
    """xflatten(seq, tuplestoo=True, safe=False): Flattens a sequence,
      giving an iterabile. If tupledtoo=True then it flattens tuples
too.
    safe=True enables the recursive reference check, do not use it for
too
      much nested structures. Examples (iterators):
    xflatten( "a" ) ==> ['a']
    xflatten( [] ) ==> []
    xflatten( [[1,[2,[],"a"]]] ) ==> [1,2,'a']
    xflatten( [()] ) ==> []
    xflatten( ([[1,[2,[],"a", ()]]],) ) ==> [1, 2, 'a']
    xflatten( (12, 34, (11,)) ) ==> (12, 34, 11)
    xflatten( (12, 34, (11,)), False ) ==> [(12, 34, (11,))]
    Notes on speed:
      tuple(xflatten()) is much slower than list(xflatten()).
      tuplestoo=False makes this function faster.
      safe=True makes this function slower."""
    # Modified from: http://google.com/groups?th=957cfbd2e46ac001
    if safe and isrecursive(seq):
        raise TypeError, "given structure contains a recursive
reference."
    if tuplestoo:
        if seq.__class__ not in (list, tuple):
            yield seq
        else:
            stack = [iter(seq)]
            while stack:
                for item in stack[-1]:
                    if item.__class__ in (list, tuple):
                        stack.append(iter(item))
                        break
                    yield item
                else:
                    stack.pop()
    else:
        if not seq.__class__ is list:
            yield seq
        else:
            stack = [iter(seq)]
            while stack:
                for item in stack[-1]:
                    if item.__class__ is list:
                        stack.append(iter(item))
                        break
                    yield item
                else:
                    stack.pop()


def flatten(seq, tuplestoo=True, safe=True):
    # Do not use tuple(xflatten(...)), it's slow.
    return list(xflatten(seq, tuplestoo, safe))

Bye,
bearophile




More information about the Python-list mailing list