python: как определить, является ли переменная массивом или скаляром

у меня есть функция, которая принимает аргумент NBins. Я хочу сделать вызов этой функции с помощью скаляра 50 или блока [0, 10, 20, 30]. Как я могу определить внутри функции, какова длина NBins - это? или сказать по-другому, если это скаляр или вектор?

Я попытался это:

>>> 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()
>>> 

Как видите, я не могу применить len to P, так как это не массив.... Есть что-то вроде isarray или isscalar in в Python?

спасибо

10 ответов


>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False

для поддержки любого типа последовательности, проверьте collections.Sequence вместо list.

Примечание: isinstance также поддерживает кортеж классов, проверьте type(x) in (..., ...) следует избегать и не является необходимым.

вы также можете проверить not isinstance(x, (str, unicode))


предыдущие ответы предполагают, что массив является стандартным списком python. Как кто-то, кто часто использует numpy, я бы рекомендовал очень питонический тест:

if hasattr(N, "__len__")

объединение ответов @jamylak и @jpaddison3 вместе, если вам нужно быть надежным против массивов numpy в качестве входных данных и обрабатывать их так же, как списки, вы должны использовать

import numpy as np
isinstance(P, (list, tuple, np.ndarray))

это надежно против подклассов массивов list, tuple и numpy.

и если вы хотите быть надежным против всех других подклассов последовательности (а не только списка и кортежа), используйте

import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))

почему вы должны так поступать с isinstance и не сравнивай type(P) с целевым значением? Вот пример, где мы делаем и изучаем поведение NewList, тривиальный подкласс списка.

>>> 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

несмотря на x и y сравнение как равное, обработка их type приведет к различному поведению. Однако, поскольку x является экземпляром подкласса list, используя isinstance(x,list) выдает желаемое поведение и лечит x и y таким же образом.


есть ли эквивалент isscalar () в numpy? Да.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True

в то время как подход @jamylak является лучшим, вот альтернативный подход

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True

другой альтернативный подход (использование класса имя свойства):

N = [2,3,5]
P = 5

type(N).__name__ == 'list'
True

type(P).__name__ == 'int'
True

type(N).__name__ in ('list', 'tuple')
True

Не нужно ничего импортировать.


просто использовать size вместо len!

>>> from numpy import size
>>> N = [2, 3, 5]
>>> size(N)
3
>>> N = array([2, 3, 5])
>>> size(N)
3
>>> P = 5
>>> size(P)
1

>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False

Вы можете проверить тип данных переменной.

N = [2,3,5]
P = 5
type(P)

это даст вам положить как тип данных P.

<type 'int'>

чтобы вы могли различать, что это целое число или массив.


Я удивлен, что такой основной вопрос, похоже, не имеет немедленного ответа на python. Мне кажется, что почти все предлагаемые ответы используют какой-то тип проверка, которая обычно не рекомендуется в python, и они кажутся ограниченными конкретным случаем (они терпят неудачу с различными числовыми типами или общими итерационными объектами, которые не являются кортежами или списками).

для меня лучше всего работает импорт numpy и использование массива.размер, например:

>>> a=1
>>> np.array(a)
Out[1]: array(1)

>>> np.array(a).size
Out[2]: 1

>>> np.array([1,2]).size
Out[3]: 2

>>> np.array('125')
Out[4]: 1

дополнительные услуги:

>>> len(np.array([1,2]))

Out[5]: 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