一、迭代器
1、定义
如果一个对象可以一次产生另一个对象(通常在 for 循环中),那么第一个对象会被认为是可迭代对象
Python 的迭代协议要求 __iter__() 返回一个特殊的迭代器对象,该对象必须实现 __next__()方法,并使用 StopIteration 异常来通知迭代的完成
特别是,如果将对象传递给内置的 iter() 函数会返回迭代器的话,说明对象是可迭代的。在内部,iter() 函数会检查传入的对象,首先查找 __iter__() 方法,尽管对象被认为是可迭代的,但真正做所有工作的是迭代器,迭代器的第一个方法是 __iter__(),迭代器本身也应该始终是可迭代的,第二个方法是 __next__() 方法,里面包括异常的抛出
"""
通过调用 SquaresIter 迭代器实现自定义 Squares 可迭代对象
"""
class Squares:
def __init__(self, count):
self.count = count
def __iter__(self):
return SquaresIter(self.count)
class SquaresIter:
def __init__(self, count):
self.count = count
self.current = 0
def __iter__(self):
return self
def __next__(self):
value = self.current ** 2
self.current += 1
if self.current > self.count:
raise StopIteration
return value
if __name__ == '__main__':
s = Squares(5)
print(s)
s_iter = iter(s)
print(next(s_iter))
print(next(s_iter), '\n')
print([item for item in s_iter])
print(next(s_iter))
<__main__.Squares object at 0x7fc0404b8780>
0
1
[4, 9, 16]
Traceback (most recent call last):
File "/home/10333752@zte.intra/PycharmProjects/pythonTestProject/learning/MyselfIterator1.py", line 40, in <module>
print(next(s_iter))
File "/home/10333752@zte.intra/PycharmProjects/pythonTestProject/learning/MyselfIterator1.py", line 26, in __next__
raise StopIteration
StopIteration
二、同时迭代多个序列
zip(a, b)的工作原理是创建出一个迭代器,迭代的长度和其中最短的输入序列相同 itertools.zip_longest() 可将最长的输入序列迭代出来
from itertools import zip_longest
from MyselfIterator1 import Squares
a = [1, 2, 3]
b = ['x', 'y', 'z']
c = ['A', 'B', 'C', 'D', 'E']
d = Squares(4)
r1 = zip(a, b, c)
print(r1, type(r1))
for item in r1:
print(item)
r2 = zip_longest(a, b, c, d)
print(r2, type(r2))
for item in r2:
print(item)
<zip object at 0x7f0126e39a48> <class 'zip'>
(1, 'x', 'A')
(2, 'y', 'B')
(3, 'z', 'C')
<itertools.zip_longest object at 0x7f0126e3db38> <class 'itertools.zip_longest'>
(1, 'x', 'A', 0)
(2, 'y', 'B', 1)
(3, 'z', 'C', 4)
(None, None, 'D', 9)
(None, None, 'E', None)