在Python中,如何确定对象是否可迭代?

有没有类似isiterable的方法? 到目前为止,我发现的唯一解决方案是致电

hasattr(myObj, '__iter__')

但是我不确定这有多愚蠢。


#1楼

根据Python 2词汇表 ,可迭代项是

您可以使用__iter__()__getitem__()方法定义的所有序列类型(例如liststrtuple )以及一些非序列类型(例如dictfile以及任何类的对象__getitem__() 。 Iterables可用于for循环以及需要序列的许多其他地方(zip(),map()等)。 将可迭代对象作为参数传递给内置函数iter()时,它将返回该对象的迭代器。

当然,考虑到Python的通用编码风格是基于“请求宽容比允许容易”这一事实,因此,人们普遍期望使用

try:
    for i in object_in_question:
        do_something
except TypeError:
    do_something_for_non_iterable

但是,如果需要显式检查它,则可以通过hasattr(object_in_question, "__iter__") or hasattr(object_in_question, "__getitem__")来测试是否可迭代。 您需要检查两者,因为str没有__iter__方法(至少在Python 2中没有),并且generator对象没有__getitem__方法。


#2楼

我经常在脚本中发现方便的方法来定义iterable函数。 (现在结合了Alfe建议的简化):

import collections

def iterable(obj):
    return isinstance(obj, collections.Iterable):

因此,您可以以可读性强的形式测试任何对象是否可迭代

if iterable(obj):
    # act on iterable
else:
    # not iterable

就像使用callable函数一样

编辑:如果您已安装numpy,则可以执行以下操作:从numpy import iterable ,这就像

def iterable(obj):
    try: iter(obj)
    except: return False
    return True

如果您没有numpy,则可以简单地实现此代码或上面的代码。


#3楼

  1. 检查__iter__可以在序列类型上使用,但是在Python 2中的字符串上会失败。 我也想知道正确的答案,在此之前,这是一种可能性(也适用于字符串):

     try: some_object_iterator = iter(some_object) except TypeError as te: print some_object, 'is not iterable' 

    内置的iter检查__iter__方法,如果是字符串,则检查__getitem__方法。

  2. 另一种通用的pythonic方法是假定一个可迭代的对象,如果它不适用于给定的对象,则将优雅地失败。 Python词汇表:

    通过检查对象的方法或属性签名而不是通过与某种类型对象的显式关系来确定对象类型的Python编程风格(“如果它看起来像鸭子,并且像鸭子一样嘎嘎叫,那一定是鸭子 。”)通过强调接口经过精心设计的代码(而不是特定类型)通过允许多态替换来提高其灵活性。 鸭式输入避免使用type()或isinstance()进行测试。 取而代之的是,它通常采用EAFP(比授权更容易获得宽恕)风格的编程。

    ...

     try: _ = (e for e in my_object) except TypeError: print my_object, 'is not iterable' 
  3. collections模块提供了一些抽象基类,这些基类允许询问类或实例是否提供特定功能,例如:

     from collections.abc import Iterable if isinstance(e, Iterable): # e is iterable 

    但是,这不会检查可通过__getitem__进行迭代的类。


#4楼

这还不够: __iter__返回的对象必须实现迭代协议(即next方法)。 请参阅文档中的相关部分。

在Python中,一个好的做法是“尝试一下”而不是“检查”。


#5楼

您可以尝试以下方法:

def iterable(a):
    try:
        (x for x in a)
        return True
    except TypeError:
        return False

如果我们可以使生成器在其上进行迭代(但不要使用生成器以免占用空间),那么它是可迭代的。 好像是“ duh”之类的东西。 为什么首先需要确定变量是否可迭代?


#6楼

try:
  #treat object as iterable
except TypeError, e:
  #object is not actually iterable

不要运行检查以查看您的鸭子是否真的是鸭子,以查看它是否可迭代,请像对待鸭子一样对待它,否则请抱怨。


#7楼

鸭打字

try:
    iterator = iter(theElement)
except TypeError:
    # not iterable
else:
    # iterable

# for obj in iterator:
#     pass

类型检查

使用抽象基类 。 他们至少需要Python 2.6,并且仅适用于新型类。

from collections.abc import Iterable   # import directly from collections for Python < 3.3

if isinstance(theElement, Iterable):
    # iterable
else:
    # not iterable

但是, iter()更加可靠,如文档所述

检查isinstance(obj, Iterable)会检测已注册为Ite

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值