Python的iterator和generator相关概念简述
前言
前段时间重新捡起了python,很多之前接触过的概念已经很陌生了,特别是一些具有明显Python风格的内容一度让我晕头转向,本文就python之中的迭代器(iterator),生成器(generator)和其他一些相关的概念做了一番整理。
迭代器(iterator)
首先,迭代器是一个用来访问 可遍历的对象 的对象。可遍历的对象有很多,最普遍的就是list(列表)。迭代器的原生形式就是for循环遍历列表。
不使用for循环而使用迭代器的原因是t优化代码,提升效率,节约资源。迭代器对象从被遍历者的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只往前不后退。
注意,迭代器是由可迭代对象提供(或产生)的
#可遍历的对象
iterable = [1,3,5,7,9]
# 生成对应的迭代器
iterator = iter(iterable)
# 访问可遍历对象的下一个元素
# 如果访问到尽头会抛出异常,否则可以一直访问下去
while True:
try:
print(next(iterator))
except:
pass
迭代器只有两个基本方法 iter() 和 next(),相应地,若要使一个自定义的类的对象可以被迭代器遍历,则需要实现 __iter()__ 和 __next()__ 这两个特殊方法(接口)。
且,迭代器本身也是一个可遍历对象,可以被其他迭代器遍历(因为包含有__iter() 接口)。
class MyIterator:
def __init__():
pass
def __iter__(self):
pass
def __next__(self):
pass
生成器(generator)
首先,生成器属于迭代器,故也是一个可迭代对象,且,生成器只由生成器函数或者生成器表达式自动产生,生成器函数可以简单理解为包含有yield关键字的python函数。
同理,使用生成器的原因是为了t优化代码,提升效率,节约资源
# 一个简单的生成器函数:
def my_gen_function():
for i in range(10):
yield i
如何理解yield关键字呢?我在此提供一个简单的思路:yield关键字是一种功能稍有不同的return关键字。我们都知道,return关键字使函数可以返回一个结果,且return之后的函数代码都不会再运行,且我们在使用带有return关键字的函数时,可以使用赋值语法:
def add(a,b):
return a + b
result = add(1,2)
于是我们可以发现,yield在这方面的特性和return基本一致,即,yield也可以返回一个值,yield后面的代码不会运行,且也可以使用赋值语法:
def pow(a,n):
for r in range(n):
yield a
a = a*a
result = pow(2,3)
以下是yield和return的相同和不同之处:
| 比较内容 | return关键字 | yield关键字 |
|---|---|---|
| 作用概述 | 返回一个值 | 返回一个值, 是生成器函数的标志语法 |
| 赋值语法 r = func() | 得到返回的值 | 得到一个生成器 |
| 执行之后 | 标志着函数运行结束 | 封存函数当前状态, 调用next( r )方法从下一行开始继续执行 |
上文中我们已经提到,迭代器是由可迭代对象产生的,这只是一个笼统的表述,在这里我们再深入一步,可迭代对象存储的是数据,而迭代器实际上存储的是算法,所以一个可迭代对象理论上可以提供一种能够遍历自身所有数据的算法,因此就可以生产迭代器。而生成器的特殊之处就在于,它凸显了存储算法这个这个概念。对于一个普通的迭代器,我们其实可以简单的把它看作一个遍历数组的指针。然而,由于生成器来源于生成器函数,它可以做到让迭代脱离于数据,仅依托于算法而存在,进一步节约了资源。
def example():
i,j = 0,1
while True:
yield i
i,j = j,i+j
result = example()
上面这个方法返回一个生成器,只需要不断调用next(result),就可以不断生成斐波那契数列中的数字,却没有依赖任何一个存储大量数字的列表。
小结
| 比较项目 | 可迭代对象 | 迭代器 | 生成器 |
|---|---|---|---|
| 英文名称 | iterable | iterator | generator |
迭代器和生成器是python中非常强大的功能。本文只是对它们的基本作用进行了简单解释。更多复杂的使用技巧和语法(如迭代器特殊方法的具体实现,生成器表达式,yield from关键字和代理生成器),在文中没有提及。可参考更多进阶教程(说不定我也会写一篇)。
本文简述了Python中的迭代器和生成器。迭代器是用于访问可遍历对象的对象,提供iter()和next()方法。生成器是迭代器的一种,由生成器函数(包含yield关键字)创建,优化了代码并节约资源。通过调用next(),生成器能生成斐波那契数列等序列,而无需预先存储所有数据。
1347





