Python - 迭代器


Python 中的迭代器是表示数据流的对象。它遵循迭代器协议,要求它支持 __iter__() 和 __next__() 方法。Python 的内置方法 iter() 实现了 __iter__() 方法。它接收一个可迭代对象并返回迭代器对象。内置的 next() 函数在内部调用迭代器的 __next__() 方法,返回流中的连续项。当没有更多数据可用时,将引发 StopIteration 异常。

Python 在处理列表、元组或字符串等集合数据类型时隐式使用迭代器。这就是这些数据类型被称为可迭代的原因。我们通常使用 for 循环来迭代可迭代对象,如下所示 -

for element in sequence:
 print (element)

Python 的内置方法 iter() 实现了 __iter__() 方法。它接收一个可迭代对象并返回迭代器对象。

例子

以下代码从序列类型列表、字符串和元组中获取迭代器对象。iter() 函数还从字典返回键迭代器。然而,int id 不可迭代,因此它会产生 TypeError。

print (iter("aa"))
print (iter([1,2,3]))
print (iter((1,2,3)))
print (iter({}))
print (iter(100))

它将产生以下输出-

<str_ascii_iterator object at 0x000001BB03FFAB60>
<list_iterator object at 0x000001BB03FFAB60>
<tuple_iterator object at 0x000001BB03FFAB60>
<dict_keyiterator object at 0x000001BB04181670>
Traceback (most recent call last):
   File "C:\Users\user\example.py", line 5, in <module>
      print (iter(100))
            ^^^^^^^^^
TypeError: 'int' object is not iterable

迭代器对象有 __next__() 方法。每次调用时,它都会返回迭代器流中的下一个元素。当流耗尽时,会引发 StopIteration 错误。调用 next() 函数相当于调用迭代器对象的 __next__() 方法。

例子

it = iter([1,2,3])
print (next(it))
print (it.__next__())
print (it.__next__())
print (next(it))

它将产生以下输出-

1
2
3
Traceback (most recent call last):
   File "C:\Users\user\example.py", line 5, in <module>
      print (next(it))
            ^^^^^^^^
StopIteration

例子

您可以使用异常处理机制来捕获 StopIteration。

it = iter([1,2,3, 4, 5])
print (next(it))
while True:
   try:
      no = next(it)
      print (no)
   except StopIteration:
      break

它将产生以下输出-

1
2
3
4
5

要在 Python 中定义自定义迭代器类,该类必须定义 __iter__() 和 __next__() 方法。

在下面的示例中,Oddnumbers 是一个实现 __iter__() 和 __next__() 方法的类。每次调用 __next__() 时,数字都会增加 2,从而流式传输 1 到 10 范围内的奇数。

例子

class Oddnumbers:

   def __init__(self, end_range):
      self.start = -1
      self.end = end_range

   def __iter__(self):
      return self

   def __next__(self):
      if self.start < self.end-1:
         self.start += 2
         return self.start
      else:
         raise StopIteration

countiter = Oddnumbers(10)
while True:
   try:
      no = next(countiter)
      print (no)
   except StopIteration:
      break

它将产生以下输出-

1
3
5
7
9

异步迭代器

Python 3.10 版本开始添加了两个内置函数 aiter() 和 anext()。aiter() 函数返回一个异步迭代器对象。它是经典迭代器的异步计数器。任何异步迭代器都必须支持 __aiter__() 和 __anext__() 方法。这些方法由两个内置函数在内部调用。

与经典迭代器一样,异步迭代器给出对象流。当流耗尽时,将引发 StopAsyncIteration 异常。

在下面给出的示例中,声明了一个异步迭代器类 Oddnumbers。它实现了 __aiter__() 和 __anext__() 方法。在每次迭代中,返回下一个奇数,并且程序等待一秒钟,以便它可以异步执行任何其他过程。

与常规函数不同,异步函数称为协程,并使用 asyncio.run() 方法执行。main() 协程包含一个 while 循环,该循环连续获取奇数,并在数字超过 9 时引发 StopAsyncIteration。

例子

import asyncio

class Oddnumbers():
   def __init__(self):
      self.start = -1

   def __aiter__(self):
      return self
      
   async def __anext__(self):
      if self.start >= 9:
         raise StopAsyncIteration
      self.start += 2
      await asyncio.sleep(1)
      return self.start
      
async def main():
   it = Oddnumbers()
   while True:
      try:
         awaitable = anext(it)
         result = await awaitable
         print(result)
      except StopAsyncIteration:
         break
         
asyncio.run(main())

它将产生以下输出-

1
3
5
7
9