迭代器

迭代器指能够被内置函数 next调用并不断返回下一个值,直到最后抛出 StopIteration错误表示无法继续返回下一个值的对象称为迭代器( Iterator)。这里主要讲一下迭代器的特性,和如何简单的实现一个迭代器。

迭代器类型

[TOC]

其实在 python中,没有内置迭代器类型的对象,但是可以通过内置函数 iter()将 str、 tuple、 list、 dict、 set等类型转换成一个迭代器类型。

简单的说,就是列表,字符串,元祖并不是迭代器类型,但可以转换成迭代器类型。

我们来看下代码。可能会更好理解。

>>> s = [1,2,3]
>>> next(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator
>>> n="abc"
>>> next(n)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not an iterator

从上面的报错可以很好地看出str和list并不是一个iterator,即迭代器.
我们尝试使用iter()函数去将其转换成iterator

>>> it_n = iter(n)
>>> next(it_n)
'a'
>>> next(it_n)
'b'

很明显现在的字符串已经是一个迭代器对象了,我们使用type()函数来验证下我们的猜想.

>>> type(it_n)
<class 'str_iterator'>
>>> type(n)
<class 'str'>

很好,python已经很明确的告诉我们它已经是个str_iterator了


已经弄懂了什么是迭代器,那么我们是否自己写一个迭代器呢?

实现一个迭代器

思路:

  • 定义一个类,用来表示我们的迭代器
  • 定义初始化函数,初始化当前值,和最大迭代的次数
  • 定义next()方法,用来实现迭代,如果没到最大迭代数就将当前次数加一,达到最大次数则抛出StopIteration停止迭代.
  • 实例化我们的迭代器
class My_iterator():
def __init__(self,max_value):
self.current_value = 0
self.max_value= max_value

def __next__(self):
if self.current_value < self.max_value:
result = self.current_value
self.current_value +=1
return result
else:
raise StopIteration

下面我们实例化我们的迭代器,来验证下是否成功实现了.

if __name__ == '__main__':
my_iter = My_iterator(3)
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))

运行我们的代码
python K:/hexo/source/_posts/迭代器.py

0
1
2

看起来好像已经实现了我们的效果,我们尝试使用list()函数将其封装到一个列表里
l = list(my_iter)
然后可怕的事情发生了,解释器抛出了一个异常

TypeError: 'My_iterator' object is not iterable

它说我们所写的并不是iterable,这我也一脸懵逼啊
不过可以看出仅仅实现 next()方法的对象还不是迭代器,真正的迭代器还需要实现一个可迭代接口 Iterable。

通过查找资料:

迭代器类型 Iterator继承自可迭代类型 Iterable,可迭代 Iterable继承自 object基类,迭代器 Iterator类型包含 iter()next()方法,而可迭代类型 Iteratble仅仅包含 iter()。可迭代对象,通过 iter()返回一个迭代器对象,迭代器对象的 next()方法则实际用于被循环。

所以,我们只需要在我们类里再定义一个iter(),用来返回迭代器对象即可

def __iter__(self):
return self

导入模块检验下我们现在的my_iter是不是已经是迭代器类型

from collections import Iterator,Iterable

调用isinstance()函数进行比较,如果跟返回True,说明已经是一个迭代器类型

print(isinstance(my_iter,Iterator))
print(isinstance(my_iter,Iterable))

True
True

好了,我们已经完成了一个很基本的迭代器了.

总结笔记

凡是可作用于 for语句循环的对象都是 Iterable可迭代类型。

凡是可作用于 next()函数的对象都是 Iterator迭代器类型。

str、 tuple、 list、 dict、 set等类型是Iterable可迭代类型,但不是 Iterator迭代器;通过 Iterable可迭代类型的 iter()方法可以获得一个Iterator迭代器对象,从而使得它们可以被for语句循环。

Python的for循环本质上就是通过调用Iterable可迭代对象的 iter()方法获得一个 Iterator迭代器对象,然后不断调用 Iterator迭代器对象 next()方法实现的。

-------------本文结束感谢您的阅读-------------