Python 对于容器类型数据支持逐个进行迭代处理,迭代会对所有元素按照一个逻辑进行计算操作。因此在 Python 所有数据范围内就存在类型是否是可迭代的话题。
根据迭代的定义,我们发现迭代操作一般是一个容器类型的数据,像数字类型是无法进行迭代的,这就引申出了一个可迭代对象的概念。
可迭代 (Iterable) 对象就可以被迭代的对象,简单的说,一个对象只要实现了只要实现了__iter__() 方法,那么用 isinstance() 函数检查就是 Iterable 对象,容器类型都是可迭代对象。
类型检测
我们检测一个对象是否可迭代,可以用以下方法:
from collections.abc import Iterable
isinstance('abc', Iterable) # str
# True
isinstance([1,2,3], Iterable) # list
# True
isinstance({}, Iterable) # dict
# True
isinstance(123, Iterable) # 整数
# False
再简单说,只要对象实现了 __iter__() 方法,并且返回的是一个迭代器,那么这个对象就是可迭代对象。
比如我们常见的列表就是可迭代对象:
lst = [1, 2, 3]
dir(lst)
'''
...
'__iter__',
...
'''
hasattr(lst, '__iter__')
# True
iter(lst)
# <list_iterator at 0x7f84826a9300>
使用 iter() 会调用对应的 __iter__() 方法,这里返回的是一个列表迭代器,所以说列表就是一个可迭代对象。
常见类型
常见的可迭代对象:
- 容器类型,如集合或序列类型(如list、tuple、set、dict、str)
- 文件对象
- 在类中定义了__iter__()方法的对象,可以被认为是 Iterable 对象,但自定义的可迭代对象要能在 for 循环中正确使用,就需要保证__iter__()实现必须是正确的
- 在类中实现了如果只实现__getitem__()的对象可以通过 iter() 函数转化成迭代器但其本身不是可迭代对象。所以当一个对象能够在 for 循环中运行,但不一定是 Iterable 对象
所以,我们也可以这么说,可迭代的对象(Iterable)是指使用 iter() 内置函数可以获取迭代器(Iterator)的对象。
相关类型
此外,Python 还专门设计了 迭代器(Iterator)和生成器(Generator) 用于迭代工作的进行。在 Python 中可迭代(Iterable)、迭代器(Iterator)和生成器(Generator) 是与迭代相关的三个概念,他们是从左到右的包含关系。