> > def flatten(a): > > if not isinstance(a,(tuple,list)): return [a] > > if len(a)==0: return [] > > return flatten(a[0])+flatten(a[1:])
> The only problem with this if it is to big or to deeply nested then it > will overflow the stack? Yes, it can overflow in its current incarnation. There is a way to fix that. [WARNING WARNING: The code presented below is very evil, but I just can't resist. *grin* Please do not try to understand the code below, as it is not meant to be read by humans. If you are just learning Python, please skip this message.] There's a way to systematically transform it so that it doesn't overflow, by using "trampolining-style" programming. This technique turns any recursive function into one that only consumes a constant amount of stack space. It's used by programming language theory folks, despite being utterly weird. *grin* I think I wrote a brief introduction to the topic on Python-Tutor list, and have also applied it in a small project (PyScheme). For your (or my?) amusement, here's the transformed flatten() function in trampolined style: ### def flatten(a): """Flatten a list.""" return bounce(flatten_k(a, lambda x: x)) def bounce(thing): """Bounce the 'thing' until it stops being a callable.""" while callable(thing): thing = thing() return thing def flatten_k(a, k): """CPS/trampolined version of the flatten function. The original function, before the CPS transform, looked like this: def flatten(a): if not isinstance(a,(tuple,list)): return [a] if len(a)==0: return [] return flatten(a[0])+flatten(a[1:]) The following code is not meant for human consumption. """ if not isinstance(a,(tuple,list)): return lambda: k([a]) if len(a)==0: return lambda: k([]) def k1(v1): def k2(v2): return lambda: k(v1 + v2) return lambda: flatten_k(a[1:], k2) return lambda: flatten_k(a[0], k1) ### This actually does something useful. ### >>> flatten([1, [2, [3, 4]]]) [1, 2, 3, 4] ### Best of all, it does not stack-overflow. We can test this on an evil constructed example: ### >>> def makeEvilList(n): ... result = [] ... for i in xrange(n): ... result = [[result], i] ... return result ... >>> evilNestedList = makeEvilList(sys.getrecursionlimit()) >>> assert range(sys.getrecursionlimit()) == flatten(evilNestedList) >>> ### And it does work. That being said, "trampolined-style" is just evil in Python: I would not want to inflict that code on anyone, save in jest. *grin* _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor