python迭代器
在学习爬虫的时候认识到到迭代我就顺便记录下面
什么是迭代
for遍历就是迭代
for循环能遍历的就是可迭代,不能遍历的就是不可迭代
for循环是怎么判断他是可迭代的,一个可迭代对象都有一个 __iter__()
方法,就是里面有__iter__()
方法,就是可迭代
迭代的基本演示
比如下面这个代码就是可迭代
1 | a = [1, 2, 3, 4] |
结果
1 | 1 |
下面是不可迭代
1 | for i in 123: |
结果
1 | Traceback (most recent call last): |
判断是否是可迭代可以用collections.abc
模块里面的Iterable
1 | from collections.abc import Iterable |
结果
1 | True |
什么是可迭代对象__iter__()
方法
我们可以看一下能迭代的里面都是有什么方法
查看列表里方法
查看列表全部方法里面有
__iter__()
方法1
2
31,2,3] a=[
dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']查看元组里方法
他里面也有
__iter__()
方法1
2
31,2,3) a=(
dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']查看字典里方法
他里面也有
__iter__()
方法1
2
3'a':'a','b':'b'} a={
dir(a)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
使用这个方法
代码,可以看见他是一个listiterator(列表迭代器)对象
1 | 'a','b'] a=[ |
在__iter__()
方法里面有下面这么多的方法,
1 | ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__'] |
其中__length_hint__()
,__next__()
和__setstate__()
方法名 | 作用 |
---|---|
__length_hint__() |
元素数量 |
__next__() |
方法也允许您执行操作,并且必须返回序列中的下一个项目 |
__setstate__(开始位置) |
位置信息来重建文件对象,就是指定开始循环的位置 |
__length_hint__()
方法
for循环是怎么知道数组他有几个,用的就是__iter__()
方法里面__length_hint__()
方法
代码
1 | 1,2,3] a=[ |
__next__()
方法
方法也允许您执行操作,并且必须返回序列中的下一个项目
他会一个一个的去执行下一个
代码
1 | a=a=[1,2,3,4].__iter__() |
结果
1 | 1 |
__setstate__()
方法
位置信息来重建文件对象,就是指定开始循环的位置
代码我指定的是2
1 | a=a=[1,2,3,4,5,6,7].__iter__() |
结果他是从第三个开始的
1 | 3 |
手写迭代器
__iter__()
方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成
__next__()
方法(Python 2 里是 next())会返回下一个迭代器对象
代码
1 | # 创一个类 |
结果
1 | <__main__.Iterative_generation object at 0x7f863bfc69a0> |
手写迭代器可以for
StopIteration
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__()
方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代
我们可以用任意可以迭代的测试一下
1 | # iter() 函数用来生成迭代器 |
下面的iter() 函数用来生成迭代器
结果,可以看见他报了一个StopIteration错,应为他就只能迭代三次。上面我执行了四次就报了一个StopIteration
1 | Traceback (most recent call last): |
手写迭代器可以for
代码
1 | # 创一个类 |
iter() 函数用来生成迭代器
raise关键字用于引发异常,您可以定义要引发的错误类型以及要向用户打印的文本
StopIteration异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
结果
1 | 0 |