在计算机中,迭代一般是指反复重复循环,直到到达某个条件为止。在python中可以理解为,能用于for循环的,是可以迭代的。
迭代器和可迭代对象迭代 iterative
可迭代对象 iterable
迭代器 iterator
一般来说,我们认为能够用于for循环的,就是可迭代对象,能使用next()调用下一个对象的,就是迭代器。这里我们可以发现,之前我们提到的生成器,也是迭代器。
当然,在python中,我们也可以通过代码来判断一个对象是否是可迭代对象,或者是迭代器。
from collections.abc import Iterable, Iterator
def check_iterable(x, name):
if isinstance(x, Iterable):
print(name, "是可迭代对象")
else:
print(name, "不是可迭代对象")
def check_iterator(x, name):
if isinstance(x, Iterator):
print(name, "是迭代器")
else:
print(name, "不是迭代器")
if __name__ == "__main__":
t1 = [i for i in range(5)]
check_iterable(t1, "列表")
check_iterator(t1, "列表")
t2 = (i for i in range(5))
check_iterable(t2, "生成器")
check_iterator(t2, "生成器")
t3 = {i: i + 1 for i in range(5)}
check_iterable(t3, "字典")
check_iterator(t3, "字典")
我们执行这个程序,得到了这样的结果
转换为迭代器列表 是可迭代对象
列表 不是迭代器
生成器 是可迭代对象
生成器 是迭代器
字典 是可迭代对象
字典 不是迭代器
同样是可以通过for循环遍历,为什么生成器就是迭代器,但是列表和字典就不是迭代器呢?
原因是,迭代器从一开始的时候,并没有得到全部的结果,而是通过调用next()得到了下一个结果。虽然迭代器可以被遍历,列表同样也可以被遍历,但是,它们不是一回事。比如,之前我们在生成器中提到的,迭代器可以表示一个无穷无尽的数列,但是列表显然不可以,所以,列表也不会是迭代器。
但是,我们可以通过iter(),创建迭代器对象,比如说,我们通过iter()将列表转换为迭代器。
from collections.abc import Iterator def check_iterator(x, name): if isinstance(x, Iterator): print(name, "是迭代器") else: print(name, "不是迭代器") if __name__ == "__main__": t1 = [i for i in range(5)] check_iterator(t1, "列表转换前") t2 = iter(t1) check_iterator(t2, "列表转换后") print(t2) print(next(t2))
从这里,我们可以看出,转换前的列表不是迭代器,使用iter转换后是迭代器,同时也可以使用next()函数。
创建迭代器如果你要创建一个类作为迭代器,那么要实现两个方法
__iter__() 该方法返回一个迭代器,此处可以返回自己
__next__() 该方法返回下一个迭代器对象
其中,如果你要为迭代器设置终止标志的话,需要抛出StopIteration异常,通过for循环遍历该迭代器时,会在StopIteration处结束
from collections.abc import Iterator def check_iterator(x, name): if isinstance(x, Iterator): print(name, "是迭代器") else: print(name, "不是迭代器") class XiaIterator: """ 作者:瞎老弟 时间:2021-10-29 联系方式:qq1413274264 说明:一个自建的迭代器类 """ def __init__(self, num): self.num = num def __iter__(self): self.s = 0 return self def __next__(self): if self.s < self.num: self.s += 1 return self.s else: # 通过for循环使用,会在StopIteration处停止 # 如果是通过next()调用,会在最后抛出StopIteration异常 raise StopIteration if __name__ == "__main__": for i in XiaIterator(20): print(i) check_iterator(XiaIterator(20), "瞎老弟自建的迭代器类")补充说明
你可能在其他地方,也能看到老版本的写法,如下所示
from collections.abc import Iterator 新版本是这样写的
from collections import Iterator 老版本是这样写的
这两种方式没什么区别,是一样的,只不过后面的那种在python的新版本中不再允许被使用了而已,如果你使用的是3.8以及以前的python版本,使用老版本的写法也是一样的。



