python学习笔记 | 迭代器&生成器
迭代器(iterator)
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件。
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
i = iter('abc') # 定义一个迭代器对象i,该对象定义了一个__next__方法,用于逐一访问容器中的元素
i # <str_iterator at 0x10b5199a0>
i.__next__() # 或next(i)
生成一个迭代器:
class Dragon:
def __init__(self,count):
self.count = count
def __iter__(self):
return self
def __next__(self):
self.count-=1
if self.count == 1:
print("别杀了,别杀了,龙妈只有一条龙了!")
raise StopIteration
return self.count
D = Dragon(3)
模拟range方法
class Range:
def __init__(self, start, end, step):
self.start = start
self.end = end
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.start >= self.end:
raise StopIteration
rel = self.start
self.start += self.step
return rel
for i in Range(1, 9, 2): print(i,end=',') # 1,3,5,7,
模拟斐波那契数列
class Fib:
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
self.a,self.b = self.b,self.a+self.b
return self.a
for i in Fib():
if i>1000:break
print(i,end=',') # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
生成器(generator)
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
def G(count):
while count > 1:
yield count
count-=1
G(5) # <generator object G at 0x10b569ac0>
g = G(5)
g = (i for i in range(1,6))
g.__next__() # 5
g.__next__() # 4
这个yield的主要效果,就是可以使函数中断,并保存中断状态
中断后,下一次调用这个函数,从上次yield的下一句开始执行
def Dragon(count):
while count > 0:
yield f'龙妈还剩{count}条龙'
count -= 1
D = Dragon(3)
next(D) # '龙妈还剩3条龙'
next(D) # '龙妈还剩2条龙'
next(D) # '龙妈还剩1条龙'
next(D) # Traceback (most recent call last):
# File "<input>", line 1, in <module>
# StopIteration
模拟斐波那契数列:
def Fib(num):
a = 0
b = 1
while b < num:
yield b
a,b = b,a+b
F = Fib(1000)
for f in F:
print(f,end=',') # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,