is_iterable function.

Neil Cerutti horpner at yahoo.com
Thu Jul 26 18:10:55 EDT 2007


On 2007-07-26, George Sakkis <george.sakkis at gmail.com> wrote:
> That's not the only problem; try a string element to see it
> break too. More importantly, do you *always* want to handle
> strings as iterables ?
>
> The best general way to do what you're trying to is pass
> is_iterable() as an optional argument with a sensible default,
> but allow the user to pass a different one that is more
> appropriate for the task at hand:
>
> def is_iterable(obj):
>     try: iter(obj)
>     except: return False
>     else: return True

> def flatten(obj, is_iterable=is_iterable):

That makes good sense.

Plus the subtly different way you composed is_iterable is clearer
than what I originally wrote. I haven't ever used a try with an
else.

>     if is_iterable(obj):
>         for item in obj:
>             for flattened in flatten(item, is_iterable):
>                 yield flattened
>     else:
>         yield obj
>
> By the way, it's bad design to couple two distinct tasks:
> flattening a (possibly nested) iterable and applying a function
> to its elements. Once you have a flatten() function,
> deeply_mapped is reduced down to itertools.imap.

I chose to implement deeply_mapped because it illustrated the
problem of trying to catch a TypeError exception when one might
be thrown by some other code. I agree with your opinion that it's
a design flaw, and most of my problems with the code were caused
by that flaw.

-- 
Neil Cerutti



More information about the Python-list mailing list