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

otm*_*ger 258 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()
>>> 
Run Code Online (Sandbox Code Playgroud)

正如你看到的,我不能申请lenP,因为它不是一个数组....有什么样isarrayisscalar在Python?

谢谢

jam*_*lak 347

>>> isinstance([0, 10, 20, 30], list)
True
>>> isinstance(50, list)
False
Run Code Online (Sandbox Code Playgroud)

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

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

你可能还想检查一下 not isinstance(x, (str, unicode))

  • 虽然这是一个很好的答案,`collections.Sequence`也是字符串的ABC,所以应该考虑到这一点.我正在使用类似`如果type(x)不是str和isinstance(x,collections.Sequence):`.这不是很好,但它是可靠的. (3认同)
  • 谢谢,我没有想到将`list`转换为标量会出错...谢谢 (2认同)
  • @ bbenne10当然可以,但是要避免使用“ type”,并且还要在Python 2上检查“ not isinstance(x,(str,unicode))” (2认同)
  • 不幸的是,“isinstance(np.array(1), (collections.abc.Sequence, np.ndarray))”(即 numpy 标量)返回“True”,但“np.array(1)[0]”是一个“索引错误” (2认同)

jpa*_*on3 111

以前的答案假设该数组是python标准列表.作为经常使用numpy的人,我推荐一个非常pythonic测试:

if hasattr(N, "__len__")
Run Code Online (Sandbox Code Playgroud)

  • `if hasattr(N,'__ len__')和(不是isinstance(N,str))`将正确地考虑字符串. (14认同)
  • `if hasattr(N,"__ __")``也应该有效. (14认同)
  • 字符串有一个`__len__`属性(所以我猜,从技术上讲,它不是一个标量类型) (12认同)
  • 还考虑了 Python 3 上的 dict (2认同)

sco*_*owe 39

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

import numpy as np
isinstance(P, (list, tuple, np.ndarray))
Run Code Online (Sandbox Code Playgroud)

这对list,tuple和numpy数组的子类很有用.

如果你想要对所有其他序列子类(不仅仅是列表和元组)具有健壮性,请使用

import collections
import numpy as np
isinstance(P, (collections.Sequence, np.ndarray))
Run Code Online (Sandbox Code Playgroud)

为什么要用这种方式做事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
Run Code Online (Sandbox Code Playgroud)

尽管xy比较相同,处理它们type会导致不同的行为.然而,由于x是的子类的实例list,使用isinstance(x,list)得到所需的行为和治疗xy以相同的方式.

  • 这是最适合我的需求的答案。我也刚刚添加了一套。因为我不想对命令强硬。`isinstance(P, (列表, 元组, 集合, np.ndarray))` (4认同)

jmh*_*mhl 30

numpy中是否有等同于isscalar()的东西?是.

>>> np.isscalar(3.1)
True
>>> np.isscalar([3.1])
False
>>> np.isscalar(False)
True
Run Code Online (Sandbox Code Playgroud)

  • 这将是更好的例子:`>>> np.isscalar('abcd')`返回`True`. (6认同)
  • 好的。尽管有一个问题是 isscalar(None) 返回 False。Numpy 将其实现为 `return (isinstance(num, generic) or type(num) in ScalarType or isinstance(num, numbers.Number))` (2认同)
  • **不,可悲。** numpy.isscalar()函数存在许多无法调和的设计缺陷,将来可能会在某些修订版本中弃用。释义[官方文档](https://docs.scipy.org/doc/numpy/reference/generated/numpy.isscalar.html):“在几乎所有情况下,`np.ndim(x)== 0`应该是而不是`np.isscaler(x)`,因为前者对于0d数组也将正确返回true。” 因此,对于numpy.isscalar()来说,健壮的向前兼容替代方案是琐碎地包装numpy.ndim():例如,def is_scalar(obj):return np.ndim(obj)== 0` (2认同)

Suk*_*lra 17

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

>>> N=[2,3,5]
>>> P = 5
>>> type(P) in (tuple, list)
False
>>> type(N) in (tuple, list)
True
Run Code Online (Sandbox Code Playgroud)

  • 如果对答案不满意的人也给出了理由,那将是很棒的。 (2认同)

Mar*_*rek 7

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

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

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

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

type(N).__name__ in ('list', 'tuple')
True
Run Code Online (Sandbox Code Playgroud)

无需导入任何东西。

  • 这样做并没有比“type(N) is list”或“type(N) is int”有任何优势。正如其他答案所提到的,进行严格的类型相等性检查通常不如“isinstance()”检查更可取,后者可以考虑子类。 (2认同)

Shi*_*hah 5

这是我发现的最好方法:检查__len__和的存在__getitem__

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

  1. 流行的方法isinstance(obj, abc.Sequence)在包括 PyTorch 的 Tensor 在内的某些对象上失败,因为它们没有实现__contains__.
  2. 不幸的是,Python 的 collections.abc 中没有任何内容可以检查 only __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
Run Code Online (Sandbox Code Playgroud)

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