У меня есть функция, которая принимает аргумент 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
к P
, так как это не массив .... Есть ли что - то подобное isarray
или isscalar
в Python?
Спасибо
type
?Ответы:
Чтобы поддерживать любой тип последовательности, отметьте
collections.Sequence
вместоlist
.примечание :
isinstance
также поддерживает кортеж классов,type(x) in (..., ...)
следует избегать проверки и не требуется.Вы также можете проверить
not isinstance(x, (str, unicode))
источник
list
чтобы получить ложные значения для скаляров ... спасибоcollections.Sequence
он также является азбукой для строки, так что это следует учитывать. Я использую что-то вродеif type(x) is not str and isinstance(x, collections.Sequence):
. Это не здорово, но это надежно.type
, а также проверяйтеnot isinstance(x, (str, unicode))
Python 2Предыдущие ответы предполагают, что массив представляет собой стандартный список Python. Как человек, который часто использует numpy, я бы порекомендовал очень питонический тест:
источник
__len__
атрибут (так что, я думаю, технически это не скалярный тип)if hasattr(N, '__len__') and (not isinstance(N, str))
будет правильно учитывать строки.Комбинируя ответы @jamylak и @ jpaddison3 вместе, если вам нужно быть устойчивым к массивным массивам в качестве входных данных и обрабатывать их так же, как списки, вы должны использовать
Это устойчиво к подклассам списков, кортежей и массивов.
И если вы хотите быть устойчивым ко всем другим подклассам последовательности (не только к списку и кортежу), используйте
Почему вы должны так поступать,
isinstance
а не сравниватьtype(P)
с целевым значением? Вот пример, где мы создаем и изучаем поведениеNewList
тривиального подкласса списка.Несмотря на
x
иy
сравнение , как равные, обработка ихtype
может привести к различному поведению. Однако, такx
как это экземпляр подклассаlist
, использованиеisinstance(x,list)
дает желаемое поведение и обрабатываетx
иy
таким же образом.источник
isinstance(P, (list, tuple, set, np.ndarray))
Есть ли в numpy эквивалент isscalar ()? Да.
источник
>>> np.isscalar('abcd')
возвратTrue
.return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))
numpy.isscalar()
функция страдает рядом несовместимых недостатков дизайна и, вероятно, будет устарела в некоторых будущих версиях. Перефразируя официальную документацию : «Почти во всех случаяхnp.ndim(x) == 0
следует использовать вместоnp.isscaler(x)
, так как первый также будет правильно возвращать true для 0d массивов».numpy.isscalar()
Таким образом, надежной альтернативой, совместимой с прямым вариантом, было бы тривиально завернутьnumpy.ndim()
: например,def is_scalar(obj): return np.ndim(obj) == 0
np.isscalar
это сбивает с толку. Официальный документ предложил использоватьnp.array.ndim
везде, тоnp.isscalar(np.array(12))
есть False, тогда как его следует считать скалярным, посколькуnp.array(12).ndim
равен 0.Хотя подход @ jamylak лучше, вот альтернативный подход
источник
type(p) in (list, )
.Другой альтернативный подход (использование свойства имени класса ):
Не нужно ничего импортировать.
источник
Вот лучший подход, который я нашел: Проверьте наличие
__len__
и__getitem__
.Вы можете спросить почему? Причины включают в себя:
isinstance(obj, abc.Sequence)
не работает на некоторых объектах, включая Tensor PyTorch, потому что они не реализуют__contains__
.__len__
и__getitem__
которое я считаю минимальными методами для объектов, подобных массиву.Так что без лишних слов:
Обратите внимание, что я добавил параметры по умолчанию, потому что большую часть времени вы можете рассматривать строки как значения, а не как массивы. Аналогично для кортежей.
источник
источник
Вы можете проверить тип данных переменной.
Он выдаст вас как тип данных P.
Так что вы можете различить, что это целое число или массив.
источник
Я удивлен, что такой основной вопрос, кажется, не имеет немедленного ответа в Python. Мне кажется, что почти во всех предлагаемых ответах используется какая-то проверка типов, которая обычно не рекомендуется в python, и кажется, что они ограничены конкретным случаем (они терпят неудачу с различными числовыми типами или общими итеративными объектами, которые не являются кортежами или списками).
Для меня лучше всего импортировать numpy и использовать array.size, например:
Обратите внимание также:
но:
источник
Просто используйте
size
вместоlen
!источник
np.size(5)
иnp.size([5])
оба ==1
, так что это не правильно различает тип (то есть, идентифицирует скаляр), который я считаю целью.preds_test [0] имеет форму (128,128,1). Давайте проверим тип данных с помощью функции isinstance (). isinstance принимает 2 аргумента. 1-й аргумент - это данные. 2-й аргумент - это тип данных isinstance (preds_test [0], np.ndarray). Это означает, что preds_test [0] является массивом.
источник
Чтобы ответить на вопрос в заголовке, прямой способ определить, является ли переменная скалярной, - попытаться преобразовать ее в число с плавающей точкой. Если вы получаете
TypeError
, это не так.источник