迭代器

迭代器
  在Python中,有三个与迭代相关的概念:迭代、可迭代对象和迭代器。迭代就是按顺序访问一系列数据中的每一项。可迭代对象就是可以通过迭代的方式获取数据的对象。典型的,Python内置的元组、列表、字符串和字典都是可迭代对象。迭代器就是实现了迭代协议(iterator protocol)的对象,也就是实现了两个特殊的方法__iter__()和__next__()。
迭代器的使用
  迭代器最常用也是最简单使用方式是使用for循环。在for循环中,会使用迭代的方式获取数据。下面是一个迭代列表中数据的例子:

number_list = (1, 20, 300, 4000, 50000)

for number in number_list:
    print(number)

  程序输出:

1
20
300
4000
50000

迭代器的工作原理
  迭代器的工作原理其实很简单:首先通过iter()获取迭代器,然后就可以多次通过next()获取数据,当已经没有数据可迭代时执行next()会抛出异常StopIteration。下面是一个展示迭代器工作原理的例子:

number_list = (1, 20, 300, 4000, 50000)

number_iter = iter(number_list)

print(next(number_iter)) # 获取1
print(next(number_iter)) # 获取20
print(next(number_iter)) # 获取300
print(next(number_iter)) # 获取4000
print(next(number_iter)) # 获取50000
print(next(number_iter)) # 已经没有数据可以迭代

  程序输出:

1
20
300
4000
50000
Traceback (most recent call last):
File "how_work.py", line 12, in
    print(next(number_iter))    # 已经没有数据可以迭代
StopIteration

  那么对于for循环,迭代器是如何工作的呢?首先for循环本质上是一个无限循环的while。形如 for item in iterable:的语句实际上是通过以下语句实现的:

iter_obj = iter(iterable) # 从可迭代对象获取迭代器

while True: # 无限循环
try:
item = next(iterable) # 获取数据
# 处理获取到的数据
except StopIteration: # 如果检测到StopIteration异常,则退出循环
break
自定义迭代器
  在Python中,可以创建自定义的迭代器。要创建迭代器,需要自定义可迭代对象,也就是需要自定义可迭代的类。这个自定义的可迭代类需要实现两个方法:__iter__()和__next__()。
  __iter__():iter()会调用__iter__()来获取迭代器。
  __next__():next()会调用__next__()来迭代地获取数据,当没有数据可迭代时,需要抛出StopIteration异常。下面是一个自定义可迭代类的例子,用来输出不大于6的偶数。

class CustomIterable(object):

    def __init__(self):
        self.num = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.num <= 6:
            self.num += 2
            return self.num
        else:
            raise StopIteration

ci = CustomIterable()

for item in ci:
    print(item)

  程序输出:

2
4
6
8

  如果你愿意,可以设计一个包含无限数据的可迭代对象,例如包含所有的自然数。这种情况下,可以不必在__next__()中抛出StopIteration异常。
  使用迭代器有很多优点。例如可以节省内存资源,不必将数据全部保存到内存中,而是每次调用顺序获取数据即可。特别在需要处理无限多个数据时尤其有用。使用迭代器还能让代码更简洁,更具有Python的风格。