Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most pythonic way to use len on a scalar?

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?

like image 582
evan54 Avatar asked Sep 19 '25 12:09

evan54


2 Answers

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.

like image 44
Jon Clements Avatar answered Sep 21 '25 03:09

Jon Clements



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!