How can I test if an argument is a sequence or a scalar?

Michael Spencer mahs at telcopartners.com
Tue Jan 10 20:59:56 EST 2006


Jean-Paul Calderone wrote:
> On 10 Jan 2006 15:18:22 -0800, sandravandale at yahoo.com wrote:
>> I want to be able to pass a sequence (tuple, or list) of objects to a
>> function, or only one.
> 
...
 > but in case you're curious, the easiest
> way to tell an iterable from a non-iterable is by trying to iterate over 
> it.  Actually, by doing what iterating over it /would/ have done:
> 
...

You can usefully wrap up this test in a convenience function that always returns 
an iterator (possibly over a zero length sequence):

  >>> for i in safe_iter(scalar_or_iterable): #do something

One definition of safe_iter is below.  Your definition may depend on the 
specific application:

Cheers

Michael


def safe_iter(obj, atomic_types = (basestring, int, float, complex)):
     """Equivalent to iter when obj is iterable and not defined as atomic.
     If obj is defined atomic or found to be not iterable, returns iter((obj,)).
     safe_iter(None) returns an empty iterator"""
     if not isinstance(obj, atomic_types):
         try:
             return iter(obj)
         except TypeError:
             pass
     return iter((obj,) * (obj is not None))

def test_safe_iter():
     assert list(safe_iter(1)) == [1]
     assert list(safe_iter("string")) == ["string"]
     assert list(safe_iter(range(10))) == range(10)
     assert list(safe_iter(xrange(10))) == list(xrange(10))
     assert list(safe_iter((1,2,3))) == [1,2,3]
     assert list(safe_iter(1.0)) == [1.0]
     assert list(safe_iter(1+2j)) == [1+2j]
     xiter = iter(range(10))
     assert safe_iter(xiter) is xiter
     xiter = (a for a in range(10))
     assert safe_iter(xiter) is xiter
     assert list(safe_iter(None)) == []





More information about the Python-list mailing list