- 迭代器的定义:具有__next__(或者next,python2)方法的对象。
- 自动可迭代的迭代器:实现__iter__方法的迭代器。通常迭代器是指自动可迭代的迭代器
- 迭代器的优势:相比使用List迭代,如果迭代数据量很大,List方法将消耗大量内存,而迭代器可以节约不少内存。获取速度和内存的提升。
- 其他优势:简单、通用、优雅
- 迭代器的终止:采用异常机制,在__next__中无法提供下一个值的时候,抛出 raise StopIteration 即可。
- 迭代器的使用技巧:a) 直接到元组,链表;b)生成一次,只使用一次。当然重新初始化也是可行的,不建议用。
失败的版本
以 Fibs 数列为例子。
>>> class Fibs():
... def __init__(self):
... self.a = 0
... self.b = 1
... def __next__(self):
... self.a, self.b = self.b, self.a+self.b
... return self.a
...
>>> fibs = Fibs()
>>> print(fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__())
1 1 2 3 5 8
>>> for f in fibs:
... print(f)
... if (f>100):
... break
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'Fibs' object is not iterable
错误提示为:Fibs的对象确实是迭代器(能够手动通过__next__给出迭代结果),但是不可自动迭代。尽管我们已经有了__next__的方法,却没有实现__iter__方法。
成功的版本
>>> class Fibs():
... def __init__(self):
... self.a = 0
... self.b = 1
... def __next__(self):
... self.a, self.b = self.b, self.a+self.b
... return self.a
... def __iter__(self):
... return self
...
>>> fibs = Fibs()
>>> print(fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__(),fibs.__next__())
1 1 2 3 5 8
>>> for f in fibs:
... print(f)
... if (f>100):
... break
...
13 21 34 55 89 144
添加了__iter__函数,该迭代器可以自动迭代了。注意,自动迭代是在手动迭代的基础上继续进行的。
- 迭代器的终止
上述例子是通过 if语句主动终止的,如果别人使用你的迭代器,不主动终止,那么肯定就爆了(我已经重新启动过电脑一次了)。主动的终止方式是采用异常 raise StopIteration 即可
>>> class Fibs():
... def __init__(self):
... self.a = 0
... self.b = 1
... def __next__(self):
... self.a, self.b = self.b, self.a+self.b
... if self.a > 100: raise StopIteration
... return self.a
... def __iter__(self):
... return self
...
>>> fibs = Fibs()
>>> for f in fibs:
... print(f)
...
1 1 2 3 5 8 13 21 34 55 89
这样便不需要额外的stop停止语句。
从迭代器到序列
直接使用truple、list函数转换
>>> class Fibs():
... def __init__(self):
... self.a = 0
... self.b = 1
... def __next__(self):
... self.a, self.b = self.b, self.a+self.b
... if self.a > 100: raise StopIteration
... return self.a
... def __iter__(self):
... return self
...
>>> fibs = Fibs()
>>> print(tuple(fibs))
(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89)
>>> fibs = Fibs()
>>> print(list(fibs))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
注意: 迭代器用完了之后,需要重置,不然得不到你要的结果。最佳的使用方式是用一次,建立一次。