关于python:在标量上使用len最简单的方法是什么?

What is the most pythonic way to use len on a scalar?

我读过这个问题

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

但是当使用下面的代码时,我在np.array上得到了一个false,如下所示。

1
2
3
4
import collections

isinstance(np.arange(10), collections.Sequence)
# returns false

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

我唯一能想到的工作就是一个try except声明,如下所示:

1
2
3
4
5
a = 1
try:
    print len(a)
except TypeError:
    print 1

有没有比这更像Python的方法?


collections.Sequence只适用于序列对象,序列对象是一种非常特殊的不可重复对象。顺便说一下,numpy.ndarray不是序列(由numpy.arange返回)。

您需要测试collections.Iterable中的任何一个,它代表任何一个不可重复的对象:

1
2
3
4
5
6
7
>>> isinstance([1, 2, 3], collections.Iterable)
True
>> isinstance(np.arange(10), collections.Iterable)
True
>>> isinstance(1, collections.Iterable)
False
>>>

collections.Sized,表示与len一起工作的任何对象:

1
2
3
4
5
6
7
>>> isinstance([1, 2, 3], collections.Sized)
True
>>> isinstance(np.arange(10), collections.Sized)
True
>>> isinstance(1, collections.Sized)
False
>>>

然后,可以使用条件表达式或类似表达式来执行所需的操作:

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

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

有关collections模块中可用抽象基类的完整列表,请参阅python文档中的collections abstract基类。


我会提出另一个可能的选择:

1
length = getattr(obj, '__len__', lambda:1)()

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

我不会说它是Python,但避免了导入和异常处理。不过,我还是会比较一下,如果它是一个collections.Sized和一个条件语句,并把它放在一个名为len_or_1的辅助函数中。


虽然这不是Python,因为它使用了numpy,但这是另一个让它工作的好方法:

1
2
3
4
5
6
7
import numpy as np
a = 1
aSh = np.shape(a)
if len(aSh) == 0:
    print 1
else:
    print max(aSh)

它给出了一个应该与标量、列表和矩阵一起使用的行为。