前言
本文主要介绍Python中的迭代器和生成器,主要内容包括 迭代器概述、生成器简介。
文章目录
- 前言
- 一、迭代器简介
- 二、生成器简介
一、迭代器简介
在 Python 中,迭代器(iterator)是一个实现了迭代器协议(Iterator Protocol)的对象。该协议包含两个方法:iter() 和 next() 方法。iter() 方法返回迭代器对象本身,next() 方法返回迭代器中的下一个元素,在迭代结束时需要抛出StopIteration 异常,如:
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
# 再次调用 next() 方法将引发 StopIteration 异常
print(next(my_iterator))
输出结果:
1
2
3
4
5
Traceback (most recent call last):
File "D:\pythonCode\hello.py", line 11, in <module>
print(next(my_iterator))
^^^^^^^^^^^^^^^^^
StopIteration
iter() 方法还接受一个可选的参数,用于指定当迭代器对象中没有剩余的元素时,返回的默认值。如果不指定该参数,则默认会引发 StopIteration 异常。例如:
my_list = [1, 2, 3]
my_iterator = iter(my_list)
print(next(my_iterator, 0))
print(next(my_iterator, 0))
print(next(my_iterator, 0))
# 再次调用 next() 方法将返回指定的默认值 0
print(next(my_iterator, 0))
输出结果:
1
2
3
0
我们平时在使用 for 循环语句遍历可迭代对象时,好像并没有显性使用iter()方法,如:
my_list = [1, 2, 3]
for item in my_list:
print(item) # 输出 1, 2, 3
实际上在遍历所有对象时,python内部的实现依旧是会自动调用 iter() 函数来获取其对应的迭代器对象,然后再不断调用迭代器对象的 next() 方法来获取其中的元素,直到抛出 StopIteration 异常。这个流程如下图:
注意:迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不会后退。
二、生成器简介
在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器是一种特殊的迭代器,可以按需生成值而不是一次性生成所有值。这种特性使得生成器非常适合处理大量的数据,尤其是在处理一些无法完全载入内存的数据集的情况下,如使用 yield 实现斐波那契数列:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
#输出斐波那契数列的前 10 个数字
f = fibonacci()
for i in range(10):
print(next(f))
# 输出结果 0 1 1 2 3 5 8 13 21 34
上面的代码中,fibonacci() 函数的执行被设置成一个无限循环,这个循环在每次yield 语句之后暂停,生成器对象返回当前的值,并且在下一个循环迭代中继续执行,而不是一次性输出所有的斐波那契数值。这种按需生成数值的方法可以大大减少内存使用,特别是当在生成的数值上花费了很多计算时间时。