在标量上使用len的最pythonic方法是什么?

eva*_*n54 2 python iterable typechecking

我读了这个问题

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

但是当使用下面的代码时,我会得到一个假的np.array,如下所示.

import collections

isinstance(np.arange(10), collections.Sequence)
# returns false
Run Code Online (Sandbox Code Playgroud)

我觉得有点烦人,我不能做len(1),只是得到1.

我能想到的唯一工作是try except如下声明:

a = 1
try:
    print len(a)
except TypeError:
    print 1
Run Code Online (Sandbox Code Playgroud)

是否有更多的Pythonic方法来做到这一点?

iCo*_*dez 6

collections.Sequence仅适用于序列对象,它是一种非常特定类型的可迭代对象.顺便提及,a numpy.ndarray(由其返回numpy.arange)不是序列.

您需要测试collections.Iterable其中任何一个,它代表任何可迭代对象:

>>> isinstance([1, 2, 3], collections.Iterable)
True
>> isinstance(np.arange(10), collections.Iterable)
True
>>> isinstance(1, collections.Iterable)
False
>>>
Run Code Online (Sandbox Code Playgroud)

或者collections.Sized,代表任何与之相关的对象len:

>>> isinstance([1, 2, 3], collections.Sized)
True
>>> isinstance(np.arange(10), collections.Sized)
True
>>> isinstance(1, collections.Sized)
False
>>>
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用条件表达式或类似方法来执行您想要的操作:

print len(a) if isinstance(a, collections.Iterable) else 1

print len(a) if isinstance(a, collections.Sized) else 1
Run Code Online (Sandbox Code Playgroud)

有关collections模块中可用抽象基类的完整列表,请参阅Python文档中的集合抽象基类.


Jon*_*nts 5

我只是抛出另一个潜在的选择:

length = getattr(obj, '__len__', lambda:1)()
Run Code Online (Sandbox Code Playgroud)

所以要么__len__从对象中获取方法,要么获取一个总是返回 1 的函数,然后调用它来获取结果。

我不会说它是 Pythonic,但避免了导入和异常处理。但是,我仍然会比较它是否是collections.Sized一个条件语句,并将它放在一个名为len_or_1或其他东西的辅助函数中。