使用len函数计算一个标量的最pythonic方式是什么?

3

我阅读了这个问题:

Python:如何确定一个变量是数组还是标量

但是当使用以下代码时,对于np.array,我得到了一个“false”结果,如下所示:

import collections

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

我觉得有点烦人的是我无法执行 len(1) 并且简单地得到 1
唯一的解决方法我能想到的是使用 try except 语句,如下所示:
a = 1
try:
    print len(a)
except TypeError:
    print 1

有没有更符合Python风格的方法来完成这个任务?

3
请至少在你的“除外”语句中说明限定条件。在此处只需要捕获TypeError异常。但是,你是如何陷入首先需要这样混合类型的情况的呢? - Martijn Pieters
你链接中第二个回答存在问题吗?该回答具体提到了numpy吗? - Mark Ransom
@ Mark Ranson 嗯,我觉得它可能行。我希望有人能说:哦,当然有类似 np.len(a) 这样的东西可以做到这种事情。但似乎没有。 - evan54
@MartijnPieters 嗯,这是由于使用 numpympmath 或单个数字引起的。因此,它可以是有限的类型集(当然),但仍然很好不列出每种情况下会发生什么。 - evan54
@MartijnPieters 根据您的建议编辑了问题。 - evan54
3个回答

8

collections.Sequence 只适用于序列对象,它们是一种非常特定的可迭代对象。顺便提一下,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
>>>

或者使用collections.Sized,该对象代表任何可以使用len的对象:
>>> isinstance([1, 2, 3], collections.Sized)
True
>>> isinstance(np.arange(10), collections.Sized)
True
>>> isinstance(1, collections.Sized)
False
>>>

您可以使用条件表达式或类似的方式来实现您想要的功能:
print len(a) if isinstance(a, collections.Iterable) else 1

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

要查看collections模块中所有可用的抽象基类的完整列表,请参见Python文档中的Collections Abstract Base Classes


如果你只是想知道 len 是否可用,那么 collections.Sized 更为通用。但这取决于 OP 实际想要对对象做什么。 - Peter DeGlopper
我想我会选择collections.Sized,它似乎更通用。有点惊讶这种函数在numpy或类似的库中并不存在。 - evan54
现在最好使用collections.abc.SizedDeprecationWarning:自Python 3.3起,使用或导入'collections'中的ABC而不是'collections.abc'已被弃用,在3.10中将停止工作。 - Martin

5

我再提供一种潜在的选择:

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

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

我不会说这是 Pythonic 的,但可以避免导入和异常处理。然而,我仍然会比较它是否为 collections.Sized 并使用条件语句将其放在一个名为 len_or_1 的帮助函数中。


1
虽然这不是pythonic的,因为它在这里使用了numpy,但这是另一种使其工作的巧妙方法:
import numpy as np
a = 1
aSh = np.shape(a)
if len(aSh) == 0:
    print 1
else:
    print max(aSh)

这将提供一种行为,可与标量、列表和矩阵一起使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接