Help clean up clumsy code

Jeff Shannon jeff at
Tue Jan 4 14:33:13 EST 2005

Scott David Daniels wrote:

> Nick Coghlan wrote:
>> A custom generator will do nicely:
>> Py> def flatten(seq):
>> ...   for x in seq:
>> ...     if hasattr(x, "__iter__"):
>> ...       for y in flatten(x):
>> ...         yield y
>> ...     else:
>> ...       yield x
> Avoiding LBYL gives you:
>     def flatten(seq):
>         for x in seq:
>             try:
>                 for y in flatten(x):
>                     yield y
>             except TypeError:
>                 yield x

If I'm not mistaken, this will result in infinite recursion on 
strings.  'for x in aString' will iterate over the characters in the 
string, even if the string is only a single character, so "for y in 
flatten('a'):" will not give a type error.  You'd need to add 
special-case tests to watch for this condition (and try not to be too 
special-case and allow unicode objects to pass).

Nick's version works on strings (and unicode objects) because they 
lack an __iter__() method, even though they follow the (older) 
sequence protocol.

Jeff Shannon
Credit International

More information about the Python-list mailing list