遍历的是迭代器for item in Iterator 循环的迭代器,不断调用next方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束 。
2.4 迭代器的应用场景我们发现迭代器最核心的功能就是可以通过next函数的调用来返回下一个数据值 。如果每次返回的数据值不是在一个已有的数据集合中读取的,而是通过程序按照一定的规律计算生成的,那么也就意味着可以不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来供后续依次读取,这样可以节省大量的存储(内存)空间 。
举个例子,比如,数学中有个著名的斐波拉契数列(Fibonacci),数列中第一个数为0,第二个数为1,其后的每一个数都可由前两个数相加得到:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
现在我们想要通过for...in...循环来遍历迭代斐波那契数列中的前n个数 。那么这个斐波那契数列我们就可以用迭代器来实现,每次迭代都通过数学计算来生成下一个数 。
class Fibonacci(object):def __init__(self, num):self.num = numself.a = 0self.b = 1self.current_index = 0def __iter__(self):return selfdef __next__(self):if self.current_index < self.num:result = self.aself.a, self.b = self.b, self.a + self.bself.current_index += 1return resultelse:raise StopIterationfib = Fibonacci(5)for value in fib:print(value)执行结果:
01123
小结迭代器的作用就是是记录当前数据的位置以便获取下一个位置的值
3、生成器3.1 生成器的概念
生成器是一类特殊的迭代器,它不需要再像上面的类一样写__iter__和__next__方法了, 使用更加方便,它依然可以使用next函数和for循环取值
3.2 创建生成器方法1第一种方法很简单,只要把一个列表生成式的 改成
my_list = [i * 2 for i in range(5)]print(my_list)my_generator = (i * 2 for i in range(5))print(my_generator)for value in my_generator:print(value)执行结果:[0, 2, 4, 6, 8]<generator object <genexpr> at 0x101367048>02468 3.3 创建生成器方法2在def函数里面看到有yield关键字那么就是生成器
def fibonacci(num):a = 0b = 1current_index = 0print("--11---")while current_index < num:result = aa, b = b, a + bcurrent_index += 1print("--22---")yield resultprint("--33---")fib = fibonacci(5)value = https://www.isolves.com/it/cxkf/yy/Python/2021-12-15/next(fib)print(value)value = next(fib)print(value)value = next(fib)print(value)在使用生成器实现的方式中,我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现,但是将每次迭代返回数值的return换成了yield,此时新定义的函数便不再是函数,而是一个生成器了 。简单来说:只要在def中有yield关键字的 就称为 生成器
3.4 生成器使用return关键字
def fibonacci(num):a = 0b = 1current_index = 0print("--11---")while current_index < num:result = aa, b = b, a + bcurrent_index += 1print("--22---")yield resultprint("--33---")return "嘻嘻"fib = fibonacci(5)value = https://www.isolves.com/it/cxkf/yy/Python/2021-12-15/next(fib)print(value)try:value = next(fib)print(value)except StopIteration as e:print(e.value)提示:生成器里面使用return关键字语法上没有问题,但是代码执行到return语句会停止迭代,抛出停止迭代异常 。
3.5 yield和return的对比使用了yield关键字的函数不再是函数,而是生成器 。(使用了yield的函数就是生成器)
代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
每次启动生成器都会返回一个值,多次启动可以返回多个值,也就是yield可以返回多个值
return只能返回一次值,代码执行到return语句就停止迭代,抛出停止迭代异常
3.6 使用send方法启动生成器并传参send方法启动生成器的时候可以传参数
def gen:i = 0while i<5:temp = yield iprint(temp)i+=1执行结果:In [43]: f = genIn [44]: next(f)Out[44]: 0In [45]: f.send('haha')hahaOut[45]: 1In [46]: next(f)NoneOut[46]: 2In [47]: f.send('haha')hahaOut[47]: 3In [48]:注意: 如果第一次启动生成器使用send方法,那么参数只能传入None,一般第一次启动生成器使用next函数小结
- 生成器创建有两种方式,一般都使用yield关键字方法创建生成器
- yield特点是代码执行到yield会暂停,把结果返回出去,再次启动生成器在暂停的位置继续往下执行
推荐阅读
- Python绘制多维度专题地图
- 视频调整分辨率的python代码,一如既往地实用
- 一文带你搞定TCP滑动窗口
- 太好玩了!6种Python实现「实时」显示进度条
- 简单介绍Python中异常处理用法
- 详解一个Python库,用于构建精美数据可视化web app
- python的反射到底有什么用?
- 人生苦短,必须学会的写Python代码利器
- 慎用!Python 实现微信消息轰炸
- 交换机组网与PON组网哪个好?一文了解清楚
