On 2007-07-26, George Sakkis <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list