简体   繁体   English

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

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

I read this question 我读了这个问题

python: how to identify if a variable is an array or a scalar python:如何识别变量是数组还是标量

but when using the following code I get a false on an np.array as can be demonstrated below. 但是当使用下面的代码时,我在np.array上得到一个假,如下所示。

import collections

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

I find it a bit annoying that I can't do len(1) and simply get 1 . 我觉得有点烦人,我不能做len(1)而只是得到1

The only work around I can think of is a try except statement such as the following: 我能想到的唯一工作是try except以下声明:

a = 1
try:
    print len(a)
except TypeError:
    print 1

Is there a more Pythonic way to do this? 是否有更多的Pythonic方法来做到这一点?

collections.Sequence only applies to sequence objects, which are a very specific type of iterable object. collections.Sequence仅适用于序列对象,它是一种非常特定类型的可迭代对象。 Incidentally, a numpy.ndarray (which is returned by numpy.arange ) is not a sequence. 顺便说一句, numpy.ndarray (由numpy.arange返回)不是序列。

You need to test for either collections.Iterable , which represents any iterable object: 您需要测试collections.Iterable ,它代表任何可迭代对象:

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

or collections.Sized , which represents any object that works with len : collections.Sized ,表示与len一起使用的任何对象:

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

You can then use a conditional expression or similar to do what you want: 然后,您可以使用条件表达式或类似方法来执行您想要的操作:

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

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

For a complete list of the available abstract base classes in the collections module, see Collections Abstract Base Classes in the Python docs. 有关collections模块中可用抽象基类的完整列表,请参阅Python文档中的集合抽象基类

I'll just throw in another potential option: 我只想提出另一个可能的选择:

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

So get either the __len__ method from the object, or a function that always returns 1, then call it to get your result. 因此,从对象获取__len__方法,或者始终返回1的函数,然后调用它来获取结果。

I wouldn't say it's Pythonic, but avoids an import and exception handling. 我不会说它是Pythonic,但是避免了导入和异常处理。 However, I'd still go with comparing if it's a collections.Sized and a conditional statement and put it in a helper function called len_or_1 or something. 但是,我仍然会比较它是否为collections.Sized和条件语句,并将其放在一个名为len_or_1的辅助函数中。

Although this isn't pythonic as it uses numpy here is another neat way to make this work: 虽然这不是pythonic,因为它使用numpy这是另一种巧妙的方法来使这项工作:

import numpy as np
a = 1
aSh = np.shape(a)
if len(aSh) == 0:
    print 1
else:
    print max(aSh)

which gives a behaviour that should work with scalars, lists and matrices. 这给出了一个应该与标量,列表和矩阵一起使用的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM