python的迭代器与生成器原理
迭代器
在很多面向对象的编程语言中,都有迭代器的概念,这就是为了帮助我们对数据结构进行遍历的一个工具。
对于list这些容器,因为他是支持使用下标进行访问的,所以使用迭代器和不使用迭代器区别不是很大。但是对于一些树形结构,或者散列式的容器,我们很难使用下标进行传统的遍历,而遍历的方式又具有很多的重复性,所以就产生了迭代器
python中迭代器的方式
- iter() ,获取一个容器的迭代器,迭代器只想第一个元素
- next(),返回当前迭代器所指向的元素,并顺序指向下一个元素
迭代器是一个可以记住遍历位置的对象,他从开始位置向后进行单向遍历,直到所有的元素都被访问完毕。
vec = [1,2,3,4,5]
it = iter(vec)
print(next(it))
for e in it :
print(e)
迭代器的创建
当一个类对象需要使用迭代器的时候,就需要在该类对象中实现两个方法__iter__()
和__next__()
方法
__iter__()
,该方法需要返回一个迭代器对象,这个迭代器对象需要实现__next__()
方法,并且有StopIteration
异常标识,标识迭代器的终止__next__()
,该方法需要返回迭代器的下一个对象
下面是一个简单的,从 1 → 5 1\rightarrow5 1→5的数字类,含有迭代器,每次迭代数值 + 1 +1 +1
class MyNumbers :
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 5 :
x = self.a
self.a += 1
return x
else :
raise StopIteration
my_class = MyNumbers()
it = iter(my_class)
for x in it :
print(x)
StopIteration
StopIteration 异常,他的存在就是为了标明迭代器的结束。
在上面的情况中,我们发现,当无限次的对一个迭代器进行next()
调用,南无最后就会出现StopIteration 异常
,合情合理,毕竟总不可能让他一直无休止的跑下去,得有一个终止条件
生成器
在python中,使用了yield
的函数被称为生成器
首先,他是一个函数,只是在函数中有一个关键字yield
,在每次调用该函数时,只要遇到了yield
,就会返回指向的结果,并保存当前的运行信息。
当下次调用next()
函数时,从当前位置继续顺序执行,yield
的下一行位置。
import sys
def fibonacci(n) :
a,b,cnt = 0,1,0
while True:
if cnt > n :
return
yield a
a,b = b,a+b
cnt += 1
f = fibonacci(10)
while True:
try:
print(next(f),end=" ")
except StopIteration:
sys.exit()