I read this question
python: how to identify if a variable is an array or a scalar
but when using the following code I get a false on an np.array as can be demonstrated below.
import collections
isinstance(np.arange(10), collections.Sequence)
# returns false
I find it a bit annoying that I can't do len(1) and simply get 1.
The only work around I can think of is a try except statement such as the following:
a = 1
try:
print len(a)
except TypeError:
print 1
Is there a more Pythonic way to do this?
collections.Sequence only applies to sequence objects, which are a very specific type of iterable object. Incidentally, a numpy.ndarray (which is returned by numpy.arange) is not a sequence.
You need to test for either collections.Iterable, which represents any iterable object:
>>> isinstance([1, 2, 3], collections.Iterable)
True
>> isinstance(np.arange(10), collections.Iterable)
True
>>> isinstance(1, collections.Iterable)
False
>>>
or collections.Sized, which represents any object that works with len:
>>> isinstance([1, 2, 3], collections.Sized)
True
>>> isinstance(np.arange(10), collections.Sized)
True
>>> isinstance(1, collections.Sized)
False
>>>
You can then use a conditional expression or similar to do what you want:
print len(a) if isinstance(a, collections.Iterable) else 1
print len(a) if isinstance(a, collections.Sized) else 1
For a complete list of the available abstract base classes in the collections module, see Collections Abstract Base Classes in the Python docs.
I'll just throw in another potential option:
length = getattr(obj, '__len__', lambda:1)()
So get either the __len__ method from the object, or a function that always returns 1, then call it to get your result.
I wouldn't say it's Pythonic, but avoids an import and exception handling. However, I'd still go with comparing if it's a collections.Sized and a conditional statement and put it in a helper function called len_or_1 or something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With