Python内置类型(5)--迭代器类型
2017-12-18 09:20
941 查看
指能够被内置函数
next调用并不断返回下一个值,直到最后抛出
StopIteration错误表示无法继续返回下一个值的对象称为迭代器(
Iterator)
其实以上的说法只是侠义上的迭代器的定义,在python中,迭代器还需要实现可迭代接口(
Iterable),可迭代接口需要返回的是一个迭代器对象,这样迭代器就能够被
for语句进行迭代。
迭代器对象初步认知
在python中,没有内置迭代器类型的对象,但是可以通过内置函数
iter将
str、
tuple、
list、
dict、
set等类型转换成一个迭代器对象。
>>> s = 'abc' >>> next(s) Traceback (most recent call last): File "<pyshell#27>", line 1, in <module> next(s) TypeError: 'str' object is not an iterator # 以上报错信息可以看出`str`不是迭代器 >>> it_s = iter(s) >>> next(it_s) 'a' >>> next(it_s) 'b' >>> next(it_s) 'c' >>> next(it_s) Traceback (most recent call last): File "<pyshell#31>", line 1, in <module> next(it_s) StopIteration # 以上报错信息可以看出`iter(str)`是迭代器
通过不断的调用
next(iterator)方法来获取下一个值,这样其实不怎么方便,
python提供了更为简洁的方法,即
for循环。
for循环每执行一次即相当于调用了一次
next(iterator)方法,直到捕获到
StopIteration异常退出循环。
>>> it_s = iter(s) >>> for c in it_s: print(c) a b c # 以上的例子是使用for循环遍历迭代器
模块
collections中的类型
Iterator就是迭代器的抽象基类,所有的迭代器都是
Iterator的实例。即如果一个对象是
Iterator的实例,则说明此对象是迭代器。
from collections import Iterator >>> isinstance(s,Iterator) False >>> isinstance(it_s,Iterator) True # 以上信息证实了`str`不是迭代器,而`iter(str)`是迭代器
如何自己实现一个迭代器
根据python鸭子类型的特性,我们自定义的类型中,只要实现了
__next()__方法,该方法在每次被调用时不断返回下一个值,直到无法继续返回下一个值时抛出
StopIteration异常即可(
next(iterator)实际上调用的是iterator内部的
__next()__方法)。
定义自己的迭代器
>>> class MyIter(): 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
验证
next方法是否不停返回下一个值
>>> my_iter = MyIter(3) >>> next(my_iter) 0 >>> next(my_iter) 1 >>> next(my_iter) 2 >>> next(my_iter) Traceback (most recent call last): File "<pyshell#31>", line 1, in <module> next(my_iter) StopIteration
验证对象是否可以用于
for循环
>>> my_iter = MyIter(3) >>> for i in my_iter: print(i) Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> for i in my_iter: TypeError: 'MyIter' object is not iterable
验证对象是否是
Iterator实例
>>> from collections import Iterator >>> isinstance(my_iter,Iterator) False
从上面的验证可以看出仅仅实现
__next()__方法的对象还不是迭代器,真正的迭代器还需要实现一个可迭代接口
Iterable。
Iterator
和Iterable
的关系
在模块collections中的类型
Iterator就是迭代器的抽象基类,其实它里面还定义了类型
Iterable,它是可迭代对象的抽象基类。先分别通过
help命令查看他们的定义:
>>> from collections import Iterator, Iterable >>> help(Iterator) Help on class Iterator in module collections.abc: class Iterator(Iterable) | Method resolution order: | Iterator | Iterable | builtins.object | | Methods defined here: | | __iter__(self) | | __next__(self) | Return the next item from the iterator. When exhausted, raise StopIteration | | ---------------------------------------------------------------------- | Class methods defined here: | | __subclasshook__(C) from abc.ABCMeta | Abstract classes can override this to customize issubclass(). | | This is invoked early on by abc.ABCMeta.__subclasscheck__(). | It should return True, False or NotImplemented. If it returns | NotImplemented, the normal algorithm is used. Otherwise, it | overrides the normal algorithm (and the outcome is cached). | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __abstractmethods__ = frozenset({'__next__'}) >>> help(Iterable) Help on class Iterable in module collections.abc: class Iterable(builtins.object) | Methods defined here: | | __iter__(self) | | ---------------------------------------------------------------------- | Class methods defined here: | | __subclasshook__(C) from abc.ABCMeta | Abstract classes can override this to customize issubclass(). | | This is invoked early on by abc.ABCMeta.__subclasscheck__(). | It should return True, False or NotImplemented. If it returns | NotImplemented, the normal algorithm is used. Otherwise, it | overrides the normal algorithm (and the outcome is cached). | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __abstractmethods__ = frozenset({'__iter__'})
通过上面的代码,可以清楚的看出迭代器类型
Iterator继承自可迭代类型
Iterable,可迭代
Iterable继承自
object基类,迭代器
Iterator类型包含
__iter()__和
__next()__方法,而可迭代类型
Iteratble仅仅包含
__iter__()。可迭代对象,通过
__iter()__返回一个迭代器对象,迭代器对象的
__next()__方法则实际用于被循环。
完善自己实现一个迭代器
我们现在再将MyIter类型实现可迭代接口
Iterable,即实现
__iter__()方法。
>>> class MyIter(): def __init__(self,max_value): self.current_value = 0 self.max_value = max_value def __iter__(self): return self def __next__(self): if self.current_value < self.max_value: result = self.current_value self.current_value += 1 return result else: raise StopIteration
验证对象是否可以用于
for循环
>>> my_iter = MyIter(3) >>> for i in my_iter: print(i) 0 1 2
验证对象是否是
Iterator实例
>>> from collections import Iterator >>> isinstance(my_iter,Iterator) True
总结
凡是可作用于for语句循环的对象都是
Iterable可迭代类型。
凡是可作用于
next()函数的对象都是
Iterator迭代器类型。
str、
tuple、
list、
dict、
set等类型是
Iterable可迭代类型,但不是
Iterator迭代器;通过
Iterable可迭代类型的
__iter()__方法可以获得一个
Iterator迭代器对象,从而使得它们可以被for语句循环。
Python的
for循环本质上就是通过调用
Iterable可迭代对象的
__iter()__方法获得一个
Iterator迭代器对象,然后不断调用
Iterator迭代器对象
__next()__方法实现的。
相关文章推荐
- Python的数据类型(内置类型)
- python之内置类型: 序列, 字典
- Python3回顾数据类型,迭代器
- Python扩展内置类型详解
- python_如何派生内置不可变类型并修改实例化行为
- <Python内置对象类型>
- Python实现扩展内置类型的方法分析
- python内置数据类型
- Python内置类型(4)--数值
- blog2@python数据类型及内置方法
- Python 数据类型以及迭代器和生成器
- python内置类型
- python内置类型---1
- Python中内置数据类型list,tuple,dict,set的区别和用法
- Python内置数据类型之Tuple篇
- Python3 -1-内置数据类型
- python内置数据类型:列表和元组
- 深入学习Python内置数据类型之——字典(Dictionary)
- python 内置数据类型
- (3) Python 内置类型 –- 元组