迭代器

正如我们之前看到的,在Python中我们使用“for”循环来迭代出对象中的内容:

  1. >>> for value in [0, 1, 2, 3, 4, 5]:
  2. ... print(value)
  3. ...
  4. 0
  5. 1
  6. 4
  7. 9
  8. 16
  9. 25

可以使用“for”循环(迭代)的对象称为迭代器。因此,一个迭代器也就是一个遵循了迭代协议的对象。

内置函数“iter”可以用来创建一个迭代对象,这时使用“next”函数可以来逐步迭代出内容:

  1. >>> my_iter = iter([1, 2, 3])
  2. >>> my_iter
  3. <list_iterator object at 0x10ed41cc0>
  4. >>> next(my_iter)
  5. 1
  6. >>> next(my_iter)
  7. 2
  8. >>> next(my_iter)
  9. 3
  10. >>> next(my_iter)
  11. Traceback (most recent call last):
  12. File "<stdin>", line 1, in <module>
  13. StopIteration

当没有更多元素时,迭代器就会抛出“StopIteration”异常。

迭代器类

迭代器可以部署在类中。你只需要重写“next”和“iter”方法即可。
我们写一个模仿“range”函数的类作为例子,作用是返回所有“a”和“b”之间的值:

  1. class MyRange:
  2. def __init__(self, a, b):
  3. self.a = a
  4. self.b = b
  5. def __iter__(self):
  6. return self
  7. def __next__(self):
  8. if self.a < self.b:
  9. value = self.a
  10. self.a += 1
  11. return value
  12. else:
  13. raise StopIteration

这样我们每次调用“next”时它都会让存储在内部的a前进,并且返回它的值。当它到达b时,就抛出“StopIteration”异常。

  1. >>> myrange = MyRange(1, 4)
  2. >>> next(myrange)
  3. 1
  4. >>> next(myrange)
  5. 2
  6. >>> next(myrange)
  7. 3
  8. >>> next(myrange)
  9. Traceback (most recent call last):
  10. File "<stdin>", line 1, in <module>
  11. StopIteration

但最重要的是,你可以将迭代器类用在for循环中:

  1. >>> for value in MyRange(1, 4):
  2. ... print(value)
  3. ...
  4. 1
  5. 2
  6. 3

迭代器部分练习

  1. 写一个迭代器类,返回的是所有“a”到“b”之间的数的平方。
  2. 写一个迭代器类,返回所有1到(n)之间的偶数。
  3. 写一个迭代器类,返回所有1到(n)之间的奇数。
  4. 写一个迭代器类,返回所有(n)到0之间的数。
  5. 写一个迭代器类,返回的是从第一个元素到(n)之间所有的斐波那契数列。你可以回顾下函数部分了解下什么是斐波那契数列。
    这是斐波那契数列的前几个数:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
  6. 写一个迭代器类,返回的是所有0到(n)的连续对,如(0, 1), (1, 2), (2, 3)…。