python:如何识别变量是数组还是标量

时间:2013-05-29 06:33:42

标签: python arrays variables scalar

我有一个带参数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,因为它不是数组....在python中是否有类似isarrayisscalar的内容?

感谢

14 个答案:

答案 0 :(得分:310)

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

要支持任何类型的序列,请检查collections.Sequence而不是list

注意isinstance也支持一个类元组,应该避免检查type(x) in (..., ...),这是不必要的。

您可能还想查看not isinstance(x, (str, unicode))

答案 1 :(得分:98)

以前的答案假设数组是python标准列表。作为经常使用numpy的人,我建议进行一次非常pythonic的测试:

if hasattr(N, "__len__")

答案 2 :(得分:34)

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

尽管xy比较相等,但按type处理它们会导致不同的行为。但是,由于xlist的子类的实例,因此使用isinstance(x,list)会提供所需的行为,并以相同的方式处理xy。< / p>

答案 3 :(得分:25)

在numpy中是否有等效的isscalar()?是。

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

答案 4 :(得分:15)

虽然@ jamylak的方法更好,但这是一种替代方法

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

答案 5 :(得分:3)

另一种替代方法(使用类名称属性):

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

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

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

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

无需导入任何内容。

答案 6 :(得分:3)

只需使用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

答案 7 :(得分:2)

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

答案 8 :(得分:2)

您可以检查变量的数据类型。

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

它会给你输出作为P的数据类型。

<type 'int'>

这样你就可以区分它是一个整数还是一个数组。

答案 9 :(得分:1)

我很惊讶这样一个基本问题似乎没有在python中立即得到答案。 在我看来,几乎所有提议的答案都使用某种类型 检查,这通常不在python中建议,它们似乎仅限于特定情况(它们使用不同的数字类型或不是元组或列表的通用可迭代对象失败)。

对我来说,更好的方法是导入numpy并使用array.size,例如:

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

答案 10 :(得分:1)

这是我发现的最佳方法:检查__len____getitem__是否存在。

您可能会问为什么?原因包括:

  1. 这会检测到几个有效数组中的流行对象,包括Python的本机列表和元组,NumPy的ndarray和PyTorch的Tensor。
  2. 另一个流行的方法isinstance(obj, abc.Sequence)在某些对象(包括PyTorch的Tensor)上失败,因为它们未实现__contains__
  3. 使用collections.abc更为可取,但不幸的是,Python的collections.abc中没有任何东西仅检查__len____getitem__

因此,事不宜迟:

def is_array_like(obj, string_is_array=False, tuple_is_array=True):
    result = hasattr(obj, "__len__") and hasattr(obj, '__getitem__') 
    if result and not string_is_array and isinstance(obj, (str, abc.ByteString)):
        result = False
    if result and not tuple_is_array and isinstance(obj, tuple):
        result = False
    return result

请注意,我添加了默认参数,因为大多数时候您可能希望将字符串视为值,而不是数组。元组也是如此。

答案 11 :(得分:1)

要回答标题中的问题,一种直接确定变量是否为标量的直接方法是尝试将其转换为浮点数。如果您得到TypeError,不是。

N = [1, 2, 3]
try:
    float(N)
except TypeError:
    print('it is not a scalar')
else:
    print('it is a scalar')

答案 12 :(得分:0)

preds_test [0]的形状为(128,128,1) 让我们使用isinstance()函数检查其数据类型 isinstance需要2个参数。 第一个参数是数据 第二个参数是数据类型 isinstance(preds_test [0],np.ndarray)给出Output为True。这意味着preds_test [0]是一个数组。

答案 13 :(得分:0)

由于Python的一般准则是要求宽恕而不是许可,所以我认为从序列中检测字符串/标量的最pythonic方法是检查其是否包含整数:

try:
    1 in a
    print('{} is a sequence'.format(a))
except TypeError:
    print('{} is a scalar or string'.format(a))