python------迭代器与生成器
一 . 生成器
1.介绍
通过列表生成式,可以直接创建一个列表,但是受内存限制,列表容量是有限的。
a = [i*2 for i in range(10000)
print (a)
如果列表元素可以按照某种算法推算出来,是否可以在循环的过程中不断推算出后续的元素?
这样就不必创建完整的list,从而俭省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器,generator.
a = (i*2 for i in range(10000))
for i in a:
print (i)
generator比较强大,但是如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
比如:斐波那契数列,除了第一个和第二个数之外,任意的数都可有前面两个数相加得到(1,1,2,3,5,8,......)

1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: #n只是控制循环 4 print(b) 5 a, b = b, a + b 6 7 # 相当于:t = (b, a + b) (t是一个元组) 8 # a = t[0] 9 # b = t[1] 10 #不等价于下面的 11 #a = b a = 1,b = 2,a = b, a = 2 12 #b = a +b ,b = 2 + 2 = 4 13 14 n=n+1 15 return 'done' 16 fib(100) #生成100斐波那契数

1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: #n只是控制循环 4 #print(b) 5 yield b #就变成生成器了 6 a, b = b, a + b 7 8 # 相当于:t = (b, a + b) (t是一个元组) 9 # a = t[0] 10 # b = t[1] 11 #不等价于下面的 12 #a = b a = 1,b = 2,a = b, a = 2 13 #b = a +b ,b = 2 + 2 = 4 14 15 n=n+1 16 return 'done' #异常的时候打印的一个信息 17 f = fib(10) #生成100斐波那契数 18 print(f.__next__()) 19 print(f.__next__()) 20 print("_________") #函数想停就停,随意进出 21 print(f.__next__()) 22 print(f.__next__()) 23 print(f.__next__()) 24 print("=====star loop======") 25 for i in f: 26 print(i)
补充:
异常捕捉;
还可以通过yield 实现在单线程的情况下实现并发运算的效果。
1 import time 2 def consumer(name): #消费者 3 print("%s 准备吃包子啦!" %name) 4 while True: 5 baozi = yield 6 7 print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) 8 9 c = consumer("xiaolai") 10 c.__next__() #只是为了打印print("%s 准备吃包子啦!" %name) 11 12 def producer(name): #生产者 13 c = consumer('A') 14 c2 = consumer('B') 15 c.__next__() 16 c2.__next__() #唤醒yield 17 print("老子开始准备做包子啦!") 18 for i in range(10): 19 time.sleep(1) 20 print("做了1个包子,分两半!") 21 c.send(i) 22 c2.send(i) #唤醒yield并且传值 23 24 producer("shogou")
2.说明:
生成器,只有在调用时才会生成相应的数据。(只能用循环,不能像列表一样去切片))
只记住当前位置;
只有一个 .__next__方法。 (2.X版本中next())
二. 迭代器
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型:list , tuple ,dict ,set ,str等;
一类是generator,包括生成器和带yield的generator function.
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable.
可以使用isinstance() 判断一个对象是否是Iterable对象:
>>>from collections import Iterable
>>>isinstance([], Iterable)
True
生成器不但可以作用于for循环,还可以被__next__()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
可以被__next__()函数调用并不断返回下一个值的对象称为迭代器:Iterator.(是迭代器就有__next__()方法)
>>>from collections import Iterator
>>>isinstance([], Iterator )
False
生成器都是Iterator对象,但list, dict ,str 虽然是Iterable,却不是Iterator。把list, dict ,str 等Iterable变成Iterator可以使用iter()函数:
a=[1,2,3]
type (a)
b = iter(a)
b.__next__()
小结:
Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算,Iterator甚至可以表示一个无限大的数据流,例如全体自然数。使用list是永远不可能存储全体自然数的 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了