生成器是一种特殊的迭代器,应该说更高级,它也是用于节省内存。
生成器是包含yield的函数,就这么简单。
它的特点是:在函数运行过程中,如果遇到yield,会暂停,并且返回一个值,等到下次执行时,从上次停止的地方开始
生成器写法
def counter(start_at=0): count=start_at while True: print(1) yield count # 通过yield返回 print(2) if count>10: raise StopIteration else: count+=1 c=counter() print c.next() # 可以看到第一次next停在了yield处,并且返回了count,没有打印2 # 1 # 0 for _ in range(2): print('next:', c.next()) # 可以看到下次执行从yield后开始,先打印2,然后while训练 # 2 # 1 # ('next:', 1) # 2 # 1 # ('next:', 2)
注意 yield count的写法,后面会有不同
交互的生成器
def counter(start_at=0): count=start_at while True: count=(yield count) # 通过yield获得了某个值 赋给 count print(count,'count') if count>10: raise StopIteration else: count+=1 c=counter() print(c.next()) # 0 print c.send(5) #(5, 'count') yield通过send获得5,赋给count # 6 send的同时也执行了next方法
1. send 信息给生成器
2. count = (yield count) 接收send的信息时必须这么写
3. 在send时自动执行了next
def counter(start_at=0): count=start_at while True: val=(yield count) if val is not None: count=val else: count+=1 count=counter(5) print count.next() # 5 print count.next() # 6 此时没有send,相当于send了一个None,所以count+1 print count.send(9) # 9 此时send了9,val不是None,所以count=val print count.next() # 10 count.close()
结束时也会报StopIteration
生成器表达式
和列表解析式很相似,区别在于列表解析时是一次性对所有元素进行了处理,而生成器表达式和生成器一样,是一个一个处理。
import time def func(x): return x*2^4 a = range(100) time.clock() # [func(i) for i in a] # 5.97484334364e-05 (func(i) for i in a) # 5.49832209537e-06 print(time.clock())
可以看到生成器表达式比列表解析快了将近10倍,因为他只处理了第一个元素。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人