前面的章节中,我们已经详细探讨了列表(list)、元组(tuple)、字典(dict)和集合(set)这些序列式容器的用法。这些容器都共享一个共同的特点,那就是它们都支持使用for循环来遍历存储的元素。它们也有一个别称,那就是迭代器。
从字面意义上来理解,迭代器就是支持迭代的容器。更精确地说,它是一个支持迭代的容器类对象。这里的容器可以是Python提供的基础容器,如列表、元组等,也可以是自定义的容器类对象,只要该容器支持迭代操作即可。
在《Python自定义序列》一节中,我们学习了如何定义一个序列类。但要注意的是,该序列类对象本身并不具备迭代功能,因此还不能被称为迭代器。若要自定义一个迭代器,则必须在类中实现以下两个方法:
- next(self):该方法用于返回容器的下一个元素。
- iter(self):此方法返回一个迭代器。
例如,下面是一个简单的程序,展示了如何自定义一个简易的列表容器迭代器并支持迭代操作:
程序执行结果为:输出21。
Python内置的iter()函数也可以返回一个迭代器。该函数的语法格式如下所述:
iter(obj, sentinel)是其中的两个参数。其中,obj必须是一个可迭代的容器对象;而sentinel是可选参数,如果使用该参数,则要求obj必须是一个可调用对象。
所谓的可调用对象,是指该类的实例对象能够像函数那样直接以“对象名()”的形式被调用。通过在类中添加call()方法,就可以将该类的实例对象转换为可调用对象。有关call()方法的详细信息,可以参考《Python call》等相关资料。
通常我们使用的是只有一个参数的iter()函数。通过传入一个可迭代的容器对象,我们可以获得一个迭代器。然后通过调用该迭代器中的next()方法就可以实现迭代操作。
例如,运行结果可能如下(这里只提供概念性示例):
程序执行结果为:在迭代完所有元素后,继续调用next()方抛出StopIteration异常。
这里介绍iter()函数的第二个参数的作用。如果使用该参数,则要求第一个obj参数必须传入可调用对象(即使不进行迭代)。当使用返回的迭代器调用next()方法时,它会执行obj()来调用call()方法。如果call()方法的返回值与第二个参数值相同,则会输出StopIteration异常;否则,会输出call()方法的返回值。