在python中有一种简单的方法来判断某些东西是不是序列吗?我试着这样做:
if x is not sequence
但是python不喜欢那个
答案 0 :(得分:65)
iter(x)
如果TypeError
无法迭代,则会引发x
- 但检查“接受”集合和词典,但它“拒绝”其他非序列,例如{ {1}}和数字。
另一方面,字符串(大多数应用程序想要考虑“单项”而非序列)实际上是序列(因此,除非特殊的字符串,否则任何测试都将确认他们是)。因此,这种简单的检查往往是不够的。
在Python 2.6及更高版本中,引入了抽象基类,并且在其他强大的功能中,它们为这种“类别检查”提供了更好的系统支持。
None
你会注意到字符串仍然被认为是“一个序列”(因为它们是),但至少你得到了dicts并且设置不了。如果你想从你的“序列”的概念中排除字符串,你可以使用>>> import collections
>>> isinstance([], collections.Sequence)
True
>>> isinstance((), collections.Sequence)
True
>>> isinstance(23, collections.Sequence)
False
>>> isinstance('foo', collections.Sequence)
True
>>> isinstance({}, collections.Sequence)
False
>>> isinstance(set(), collections.Sequence)
False
(但这也排除了元组,像字符串一样,是序列,但不是可变的),或明确地做:< / p>
collections.MutableSequence
品尝季节,热腾腾! - )
答案 1 :(得分:9)
我认为以下代码段可以满足您的需求:
def is_sequence(obj):
return hasattr(type(obj), '__iter__')
答案 2 :(得分:6)
因为Python&#34;坚持&#34;鸭子打字,其中一种方法是检查对象是否有某个成员(方法)。
序列具有长度,具有项目序列,并支持切片[doc]。所以,它会是这样的:
def is_sequence(obj):
t = type(obj)
return hasattr(t, '__len__') and hasattr(t, '__getitem__')
# additionally: and hasattr(t, '__setitem__') and hasattr(t, '__delitem__')
它们都是特殊方法,__len__()
应该返回项目数,__getitem__(i)
应该返回一个项目(按顺序它是 i - 项目,但是没有映射),__getitem__(slice(start, stop, step))
应该返回子序列,__setitem__
和__delitem__
就像您期望的那样。这是一个这样的契约,但对象是否真的这样做取决于对象是否遵守合同。
注意,上面的函数也会返回True
进行映射,例如: dict
,因为映射也有这些方法。要解决此问题,您可以执行更重的工作:
def is_sequence(obj):
try:
len(obj)
obj[0:0]
return True
except TypeError:
return False
但是大部分时间你都不需要这样做,只需做你想做的事情就像对象是一个序列一样,如果你愿意的话就抓住一个例外。这更像是pythonic。
答案 3 :(得分:5)
Python 2.6.5 documentation描述了以下序列类型:string,Unicode string,list,tuple,buffer和xrange。
def isSequence(obj):
return type(obj) in [str, unicode, list, tuple, buffer, xrange]
答案 4 :(得分:1)
为了完整性。 numpy库中有一个实用程序is_sequence
(“使用Python进行科学计算的基本软件包”)。
>>> from numpy.distutils.misc_util import is_sequence
>>> is_sequence((2,3,4))
True
>>> is_sequence(45.9)
False
但是它接受 sets 作为序列,并拒绝 strings
>>> is_sequence(set((1,2)))
True
>>> is_sequence("abc")
False
代码看起来有点像@adrian的代码(请参见numpy git code),有点不稳定。
def is_sequence(seq):
if is_string(seq):
return False
try:
len(seq)
except Exception:
return False
return True
答案 5 :(得分:0)
你为什么要这样做?这里的常规方法是需要某种类型的东西(序列或数字或类似文件的对象等)然后使用它而不检查任何东西。在Python中,我们通常不使用类来承载语义信息,而只是使用定义的方法(这称为“鸭子打字”)。我们也更喜欢API,我们确切地知道会发生什么;如果要更改函数的工作方式,请使用关键字参数,预处理或定义另一个函数。
答案 6 :(得分:0)
对于Python 3和2.6+,您可以检查它是否为collections.Sequence
的子类:
>>> import collections
>>> isinstance(myObject, collections.Sequence)
True
在Python 3.7中,您必须使用collections.abc.Sequence
(collections.Sequence
在Python 3.8中将被删除):
>>> import collections.abc
>>> isinstance(myObject, collections.abc.Sequence)
True
但是,这对于实现__len__()
和__getitem__()
但不(应该)子类collections.Sequence
的鸭子型序列不起作用。但它适用于所有内置的Python序列类型:列表,元组,字符串等。
虽然所有序列都是可迭代的,但并非所有可迭代的都是序列(例如,集合和字典是可迭代的,但不是序列)。选中hasattr(type(obj), '__iter__')
将返回True
的字典和集合。
答案 7 :(得分:-3)
为什么要问为什么
尝试获取长度,如果异常返回false
def haslength(seq):
try:
len(seq)
except:
return False
return True