Python:检查对象是否为序列

问题描述 投票:62回答:7

在python中,有一种简单的方法来判断某物是否不是序列?我试着做:if x is not sequence,但是python不喜欢]

python if-statement sequence sequences
7个回答
70
投票

[iter(x)将引发TypeError,如果无法迭代x -尽管“拒绝”其他非序列,例如None和数字,但该检查会“接受”集合和词典。

另一方面,字符串(大多数应用程序希望将其视为“单个项目”而不是序列)。are实际上是序列(因此,除非对字符串进行特殊处理,否则任何测试都将确认它们是正确的) 。因此,这种简单的检查通常是不够的。

在Python 2.6和更高版本中,引入了[[抽象基类,并且在其他强大的功能中,它们为此类”类别检查”提供了更好的系统支持。

>>> 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
您会注意到,字符串

still

被认为是“序列”(因为它们是[[are)),但是至少您会得到字典和命令。如果要从“存在序列”的概念中排除字符串,则可以使用collections.MutableSequence(但这也排除元组,像字符串一样,它们是序列,但不可变),或显式地执行它:import collections def issequenceforme(obj): if isinstance(obj, basestring): return False return isinstance(obj, collections.Sequence) 季节品尝,热食!-)
Python 3.3+的PS:Sequence之类的抽象基类已移至collections.abc

8
投票
def is_sequence(obj): return hasattr(type(obj), '__iter__')

7
投票
序列具有长度,具有项目序列,并支持切片[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个项目,

but不包含映射),[C0 ]应该返回子序列,并且__getitem__(slice(start, stop, step))__setitem__如您所愿。这就是这样的合同,但是对象是否真正做到这些取决于对象是否遵守合同。

Note,上面的函数还将返回__delitem__进行映射,例如True,因为映射也具有这些方法。为了克服这个问题,您可以做一个[[heavier work:

dict

但是在大多数情况下,您不需要这样做,就象对象是一个序列一样进行所需的操作,并根据需要捕获异常。这是更pythonic的。


4
投票

对于Python 3和2.6+,您可以检查它是否是def isSequence(obj): return type(obj) in [str, unicode, list, tuple, buffer, xrange] 的子类:

collections.Sequence
在Python 3.7中,您必须使用>>> import collections >>> isinstance(myObject, collections.Sequence) True (在Python 3.8中将删除collections.abc.Sequence:]
collections.Sequence

但是,这对于实现>>> import collections.abc >>> isinstance(myObject, collections.abc.Sequence) True __len__()但不(应该)子类__getitem__()的鸭子型序列不起作用。但它适用于所有内置的Python序列类型:列表,元组,字符串等。

虽然所有序列都是可迭代的,但并非所有可迭代的都是序列(例如,集合和字典是可迭代的,但不是序列)。选中collections.Sequence将返回hasattr(type(obj), '__iter__')的字典和集合。

您为什么要这样做?此处的正常方法是需要某种类型的事物(序列或数字或类似文件的对象等),然后在不检查任何内容的情况下使用它。在Python中,我们通常不使用类来携带语义信息,而只是使用定义的方法(这被称为“鸭子类型”)。我们也更喜欢那些我们确切知道期望的API。如果要更改函数的工作方式,请使用关键字参数,预处理或定义另一个函数。


4
投票
collections.Sequence

但是,这对于实现>>> import collections.abc >>> isinstance(myObject, collections.abc.Sequence) True __len__()但不(应该)子类__getitem__()的鸭子型序列不起作用。但它适用于所有内置的Python序列类型:列表,元组,字符串等。

虽然所有序列都是可迭代的,但并非所有可迭代的都是序列(例如,集合和字典是可迭代的,但不是序列)。选中collections.Sequence将返回hasattr(type(obj), '__iter__')的字典和集合。

-1
投票
为什么问为什么

尝试获取长度,如果异常返回false,则返回>]

True

-3
投票
© www.soinside.com 2019 - 2024. All rights reserved.