在本 Python 教程中,您将掌握 Python 中迭代器的优雅概念。您还将借助 __iter__() 和 __next__() 方法以及非常方便的示例,在 Python 中构建自己的迭代器。
在进入主题之前,让我们快速回顾一下什么是迭代以及什么是 Python 中的可迭代对象,我们已经在 Python 循环教程中讨论过。迭代是重复一组代码多次或直到满足特定条件的过程(例如:for 循环和 while 循环)。可迭代对象指的是可以重复或迭代的对象(例如:字符串、列表、元组等)。
在 Python 编程语言中,迭代器是一个用于在迭代中遍历可迭代对象的对象。迭代器存储迭代的状态,因此它一次返回一个项目。在 Python 中,迭代器在循环、推导式、生成器等中被内在实现。
从技术上讲,迭代器对象必须实现迭代器协议,该协议包含两个函数 __iter__() 和 __next__()。iter() 函数将可迭代对象转换为迭代器,而 next() 函数调用可迭代对象中的下一个项目。
Str_list = ['Yellow','Orange','Red']
it_obj = iter(Str_list)
print(it)
print(next(it_obj))
print(next(it_obj))
print(next(it_obj))
print(next(it_obj))
输出:
Yellow Orange Red Traceback (most recent call last): File "iter_ex.py", line 17, in print(next(it)) StopIteration
在上面的代码片段中,您可以看到迭代器的创建及其实施。
Str_list 的列表,它包含三个字符串元素 ‘Yellow’、‘ Orange’ 和 ‘Red’。iter() 函数创建了迭代器 it_obj,该函数在这里将列表转换为迭代器。print(it),期望结果是迭代器的值,即列表中的第一个元素(yellow)。但实际上,它打印的是迭代器对象。next() 的内置函数。print(next(it_obj)) 打印列表中的第一个元素,即 Yellow。 print(next(it_obj)) 打印列表中的下一个元素,即 Orange。print(next(it_obj)) 打印列表中的下一个元素,即 Red。print(next(it_obj)) 最终引发了一个 StopIteration 异常,因为列表已到达末尾,没有更多的值可以返回。由此我们了解到,通过使用 next() 函数,我们可以手动地遍历可迭代对象中的项目。
为了使其更方便,我们有另一种优雅的迭代方式,那就是 for 循环迭代。同样的例子可以用 for 循环自动实现,如下所示。
Str_list = ['Yellow','Orange','Red']
for i in Str_list:
print(i)
输出
Yellow Orange Red
在解释 FOR 循环在 Python 内部如何工作之前,请先查看下面的代码片段并进行分析。
Str_list = ['Yellow','Orange','Red']
it_ob = iter(Str_list)
while True:
try:
i = next(it_ob)
print(i)
except StopIteration:
break
输出
Yellow Orange Red
这就是 for 循环的内部实现方式。for 循环会内在地创建一个迭代器对象,然后在 while 循环中使用 next() 函数来迭代像列表这样的可迭代对象。当可迭代对象到达末尾并尝试再次迭代时,程序将停止并引发异常。
我们已经看到了迭代器在内置结构上的工作方式。现在让我们尝试创建自己的迭代器,即用户定义的版本。我们需要记住的一件事是,在创建迭代器时,我们必须实现迭代器协议。具体来说,我们必须使用 iter() 和 next()。
因此,让我们创建一个迭代器来产生偶数平方的结果。输出将采用以下形式。
class Pow:
def __iter__(self):
self.a = 0
return self
def __next__(self):
x = self.a**2
self.a = self.a + 2
return x
even = Pow()
it_ob = iter(even)
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
输出
0 4 16 36 64
当您观察上面的代码时,可以注意到代码中没有包含终止步骤,这意味着迭代器将无限迭代。为了清楚地理解这一点,让我们使用‘for 循环’来迭代我们的类 Pow。
for i in Pow():
print(i)
输出
0 4 16 36 64 100 . . .
那些无限迭代的迭代器被称为无限迭代器。在编码时,这不是一种好的做法,因此我们必须小心地在程序中包含终止语句。
所以现在我们意识到我们需要停止迭代以防止永不结束的迭代。为了实现这一点,我们在 next() 函数内部使用 StopIteration 语句,如下面的代码片段所示。
class Pow:
def __init__(self, max =0):
self.max = max
def __iter__(self):
self.a = 0
return self
def __next__(self):
if self.a<=self.max:
x = self.a**2
self.a = self.a + 2
return x
else:
raise StopIteration
even = Pow(5)
it_ob = iter(even)
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
print(next(it_ob))
输出
0 4 16 Traceback (most recent call last): File "iter_ex.py", line 47, inprint(next(it_ob)) File "iter_ex.py", line 39, in __next__ raise StopIteration StopIteration
使用 for 循环实现的相同代码如下
for i in Pow(8):
print(i)
输出
0 4 16 36 64
在程序中利用迭代器的主要好处是它们可以节省资源,这意味着除了单个内存外,不需要特殊的内存来获取所有元素。理论上,它表示可以在有限的内存中存储无限的元素。