Recursive list comprehension

Nick Craig-Wood nick at craig-wood.com
Thu Dec 9 07:46:12 CET 2004


Peter Otten <__peter__ at web.de> wrote:
>  Adam DePrince wrote:
> 
> > def flatten( i ):
> >     try:
> >         i = i.__iter__()
> >         while 1:
> >             j = flatten( i.next() )
> >             try:
> >                 while 1:
> >                     yield j.next()
> >             except StopIteration:
> >                 pass
> >     except AttributeError:
> >         yield i
> 
>  While trying to break your code with a len() > 1 string I noted that strings
>  don't feature an __iter__ attribute. Therefore obj.__iter__() is not
>  equivalent to iter(obj) for strings. Do you (plural) know whether this is a
>  CPython implementation accident or can be relied upon?

I'd like to know this too!

You can write the above as the shorter (and safer IMHO - it doesn't
catch any exceptions it shouldn't)

def flatten( i ):
    if hasattr(i, "__iter__"):
        for j in i:
            for k in flatten(j):
                yield k
    else:
        yield i


-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list