I have a function that takes the argument
NBins. I want to make a call to this function with a scalar
50 or an array
[0, 10, 20, 30]. How can I identify within the function, what the length of
NBins is? or said differently, if it is a scalar or a vector?
I tried this:
>>> N=[2,3,5] >>> P = 5 >>> len(N) 3 >>> len(P) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'int' has no len() >>>
As you see, I can’t apply
P, since it’s not an array…. Is there something like
isscalar in python?
>>> isinstance([0, 10, 20, 30], list) True >>> isinstance(50, list) False
To support any type of sequence, check
collections.Sequence instead of
isinstance also supports a tuple of classes, check
type(x) in (..., ...) should be avoided and is unnecessary.
You may also wanna check
not isinstance(x, (str, unicode))
Previous answers assume that the array is a python standard list. As someone who uses numpy often, I’d recommend a very pythonic test of:
if hasattr(N, "__len__")
Combining @jamylak and @jpaddison3’s answers together, if you need to be robust against numpy arrays as the input and handle them in the same way as lists, you should use
import numpy as np isinstance(P, (list, tuple, np.ndarray))
This is robust against subclasses of list, tuple and numpy arrays.
And if you want to be robust against all other subclasses of sequence as well (not just list and tuple), use
import collections import numpy as np isinstance(P, (collections.Sequence, np.ndarray))
Why should you do things this way with
isinstance and not compare
type(P) with a target value? Here is an example, where we make and study the behaviour of
NewList, a trivial subclass of list.
>>> class NewList(list): ... isThisAList = '???' ... >>> x = NewList([0,1]) >>> y = list([0,1]) >>> print x [0, 1] >>> print y [0, 1] >>> x==y True >>> type(x) <class '__main__.NewList'> >>> type(x) is list False >>> type(y) is list True >>> type(x).__name__ 'NewList' >>> isinstance(x, list) True
y comparing as equal, handling them by
type would result in different behaviour. However, since
x is an instance of a subclass of
isinstance(x,list) gives the desired behaviour and treats
y in the same manner.
Is there an equivalent to isscalar() in numpy? Yes.
>>> np.isscalar(3.1) True >>> np.isscalar([3.1]) False >>> np.isscalar(False) True
While, @jamylak’s approach is the better one, here is an alternative approach
>>> N=[2,3,5] >>> P = 5 >>> type(P) in (tuple, list) False >>> type(N) in (tuple, list) True
Another alternative approach (use of class name property):
N = [2,3,5] P = 5 type(N).__name__ == 'list' True type(P).__name__ == 'int' True type(N).__name__ in ('list', 'tuple') True
No need to import anything.
You can check data type of variable.
N = [2,3,5] P = 5 type(P)
It will give you out put as data type of P.
So that you can differentiate that it is an integer or an array.
>>> N=[2,3,5] >>> P = 5 >>> type(P)==type(0) True >>> type([1,2])==type(N) True >>> type(P)==type([1,2]) False
I am surprised that such a basic question doesn’t seem to have an immediate answer in python.
It seems to me that nearly all proposed answers use some kind of type
checking, that is usually not advised in python and they seem restricted to a specific case (they fail with different numerical types or generic iteratable objects that are not tuples or lists).
For me, what works better is importing numpy and using array.size, for example:
>>> a=1 >>> np.array(a) Out: array(1) >>> np.array(a).size Out: 1 >>> np.array([1,2]).size Out: 2 >>> np.array('125') Out: 1
>>> len(np.array([1,2])) Out: 2
>>> len(np.array(a)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-40-f5055b93f729> in <module>() ----> 1 len(np.array(a)) TypeError: len() of unsized object
size instead of
>>> from numpy import size >>> N = [2, 3, 5] >>> size(N) 3 >>> N = array([2, 3, 5]) >>> size(N) 3 >>> P = 5 >>> size(P) 1