369

我有一个接受参数的函数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()
>>> 

如您所见,我不能适用lenP,因为它不是数组.... python 中有类似isarrayor的东西吗?isscalar

谢谢

4

14 回答 14

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

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

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

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

于 2013-05-29T06:35:51.880 回答
147

以前的答案假设该数组是一个 python 标准列表。作为经常使用 numpy 的人,我建议对以下内容进行非常 Python 的测试:

if hasattr(N, "__len__")
于 2013-11-04T17:32:06.000 回答
66

将@jamylak 和@jpaddison3 的答案结合在一起,如果您需要对 numpy 数组作为输入具有鲁棒性并以与列表相同的方式处理它们,您应该使用

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

这对于列表、元组和 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, usingisinstance(x,list)给出了所需的行为并以相同的方式对待xy

于 2015-03-04T15:32:13.273 回答
51

numpy 中是否有等效于 isscalar() 的方法?是的。

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
>>> np.isscalar('abcd')
True
于 2015-11-13T04:53:17.300 回答
25

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

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
于 2013-05-29T06:37:21.297 回答
4

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

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

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

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

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

无需导入任何东西。

于 2013-05-29T07:13:58.887 回答
4

这是我发现的最佳方法:检查__len__and的存在__getitem__

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

  1. 流行的方法isinstance(obj, abc.Sequence)在某些对象上失败,包括 PyTorch 的张量,因为它们没有实现__contains__.
  2. 不幸的是,Python 的 collections.abc 中没有任何东西只检查__len____getitem__我觉得这是类数组对象的最小方法。
  3. 它适用于列表、元组、ndarray、张量等。

所以事不宜迟:

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

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

于 2019-02-12T11:13:01.240 回答
3
>>> N=[2,3,5]
>>> P = 5
>>> type(P)==type(0)
True
>>> type([1,2])==type(N)
True
>>> type(P)==type([1,2])
False
于 2013-05-29T06:40:59.217 回答
3

要回答标题中的问题,判断变量是否为标量的直接方法是尝试将其转换为浮点数。如果你得到TypeError,它不是。

N = [1, 2, 3]
try:
    float(N)
except TypeError:
    print('it is not a scalar')
else:
    print('it is a scalar')
于 2020-04-18T17:58:23.023 回答
2

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

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

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

<type 'int'>

这样您就可以区分它是整数还是数组。

于 2013-05-29T06:54:11.987 回答
2

只需使用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
于 2016-04-12T14:40:03.340 回答
2

我很惊讶这样一个基本的问题在 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
于 2015-08-29T16:35:52.310 回答
0

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

try:
    1 in a
    print('{} is a sequence'.format(a))
except TypeError:
    print('{} is a scalar or string'.format(a))
于 2020-09-07T14:25:27.490 回答
0

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

于 2019-06-08T10:07:18.677 回答