The Python Oracle

python: how to identify if a variable is an array or a scalar

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Take control of your privacy with Proton's trusted, Swiss-based, secure services.
Choose what you need and safeguard your digital life:
Mail: https://go.getproton.me/SH1CU
VPN: https://go.getproton.me/SH1DI
Password Manager: https://go.getproton.me/SH1DJ
Drive: https://go.getproton.me/SH1CT


Music by Eric Matyas
https://www.soundimage.org
Track title: Forest of Spells Looping

--

Chapters
00:00 Python: How To Identify If A Variable Is An Array Or A Scalar
00:36 Accepted Answer Score 550
01:46 Answer 2 Score 34
01:59 Answer 3 Score 176
02:13 Answer 4 Score 78
03:19 Thank you

--

Full question
https://stackoverflow.com/questions/1680...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #arrays #variables #scalar

#avk47



ACCEPTED ANSWER

Score 550


>>> import collections.abc
>>> isinstance([0, 10, 20, 30], collections.abc.Sequence) and not isinstance([0, 10, 20, 30], (str, unicode))
True
>>> isinstance(50, collections.abc.Sequence) and not isinstance(50, (str, unicode))
False

note: 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))

As noted by @2080 and also here this won't work for numpy arrays. eg.

>>> import collections.abc
>>> import numpy as np
>>> isinstance((1, 2, 3), collections.abc.Sequence)
True
>>> isinstance(np.array([1, 2, 3]), collections.abc.Sequence)
False

In which case you may try the answer from @jpaddison3:

>>> hasattr(np.array([1, 2, 3]), "__len__")
True
>>> hasattr([1, 2, 3], "__len__")
True
>>> hasattr((1, 2, 3), "__len__")
True

However as noted here, this is not perfect either, and will incorrectly (at least according to me) classify dictionaries as sequences whereas isinstance with collections.abc.Sequence classifies correctly:

>>> hasattr({"a": 1}, "__len__")
True
>>> from numpy.distutils.misc_util import is_sequence
>>> is_sequence({"a": 1})
True
>>> isinstance({"a": 1}, collections.abc.Sequence)
False

You could customise your solution to something like this, add more types to isinstance depending on your needs:

>>> isinstance(np.array([1, 2, 3]), (collections.abc.Sequence, np.ndarray))
True
>>> isinstance([1, 2, 3], (collections.abc.Sequence, np.ndarray))
True



ANSWER 2

Score 176


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__")



ANSWER 3

Score 78


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

Despite x and y comparing as equal, handling them by type would result in different behaviour. However, since x is an instance of a subclass of list, using isinstance(x,list) gives the desired behaviour and treats x and y in the same manner.




ANSWER 4

Score 34


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