3. Python3 中的迭代器

  • 迭代器的定义:具有__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 "", line 1, in 
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]

注意: 迭代器用完了之后,需要重置,不然得不到你要的结果。最佳的使用方式是用一次,建立一次。

你可能感兴趣的:(3. Python3 中的迭代器)