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

Question:

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?

Asked By: evan54

||

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.

Answered By: user2555451

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.

Answered By: Jon Clements

Although this isn’t pythonic as it uses numpy here is another neat way to make this work:

import numpy as np
a = 1
aSh = np.shape(a)
if len(aSh) == 0:
    print 1
else:
    print max(aSh)

which gives a behaviour that should work with scalars, lists and matrices.

Answered By: evan54

to much work…

temp = [var]
print(len(temp))
Answered By: D.F.
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.