is parameter an iterable?

Steven D'Aprano steve at REMOVETHIScyber.com.au
Tue Nov 15 17:57:59 EST 2005


On Tue, 15 Nov 2005 11:26:23 -0800, py wrote:

> Dan Sommers wrote:
>> Just do it.  If one of foo's callers passes in a non-iterable, foo will
>> raise an exception, and you'll catch it during testing
> 
> That's exactly what I don't want.  I don't want an exception, instead I
> want to check to see if it's an iterable....if it is continue, if not
> return an error code.  I can't catch it during testing since this is
> going to be used by other people.

That would be the Look Before You Leap school of thought.

That is rarely the best way of doing things in Python. (Note I said
*rarely*, not *never*.) If you insist, you would have to do something like
this:

def is_iterable(obj):
    """Returns True if obj is *probably* an iterable and False
    otherwise. Not that some weird custom objects that break the
    rules may give incorrect results.
    """ 
    if type(obj) in (type([]), type(()), type("")):
        return True
    elif hasattr(obj, next) and callable(obj.next):
        return True
    elif hasattr(obj, __getitem__):
        return True
    else:
        # I don't think I missed anything...
        return False

But in fact there is an easier way:

def is_iterable(obj):
    """Just Do It."""
    try:
        for item in obj:
            break
    except TypeError:
        return False
    return True

That works, but it has a side-effect: if you pass it an iterable that gets
consumed, you now have used up the first item of it (e.g. if you a
reading lines from a file, you've just used the first line and won't get
it back unless you reset the file pointer).

So do your test inside your code:

def foo(inputVal):
    try:
        for val in inputVal:
            # do stuff
    except TypeError, msg:
        if msg == "iteration over non-sequence":
            # handle non-iterable case
        else:
            # some other TypeError is a bug, so re-raise the exception
            raise









More information about the Python-list mailing list