我有一个以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中有isarray或isscalar之类的东西吗?

谢谢


当前回答

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

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

其他回答

虽然@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

不需要进口任何东西。

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

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

流行的方法isinstance(obj, abc.Sequence)在一些对象(包括PyTorch的Tensor)上失败,因为它们没有实现__contains__。 不幸的是,Python的集合中什么都没有。abc,只检查__len__和__getitem__,我觉得这是数组类对象的最小方法。 它适用于列表,元组,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

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

前面的回答假设数组是python标准列表。作为一个经常使用numpy的人,我推荐一个非常python化的测试:

if hasattr(N, "__len__")

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

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