当前位置: 首页 > ops >正文

【python】python进阶——生成器

目录

一、生成器介绍

1.1 生成器与迭代器的关系

1.2 生成器与return比较

二、创建生成器

方法1: 生成器函数

方法2: 生成器表达式

三、生成器的实际应用场景

3.1 处理大型文件

3.2 生成无限序列

3.3 数据管道处理

四、生成器的高级用法

4.1 使用send()方法传递值

4.2 生成器委托(yield from)

五、生成器的特点

总结


一、生成器介绍

        生成器是Python中一种特殊的迭代器,关键字是yield,它允许你按需生成值,而不是一次性计算并存储所有值。这种"惰性计算"的特性使得生成器在处理大数据集或无限序列时非常高效。

1.1 生成器与迭代器的关系

        生成器是一种特殊的迭代器,具有迭代器的所有特性,但更简洁。生成器自动实现了迭代器协议(即__iter__()和__next__()方法),并且状态挂起和恢复是自动的。

        迭代器是一个可以记住遍历位置的对象,它从集合的第一个元素开始访问,直到所有元素被访问完结束,只能往前不会后退。生成器是使用yield表达式来生成值的函数,每次调用next()时,生成器会从上次yield的位置继续执行,直到遇到yield或return(包括函数结束)为止。

        生成器是迭代器的一种,但迭代器不一定是生成器。

  • 迭代器可以通过实现类的__iter__和__next__方法来创建
  • 生成器通过函数和yield来创建。

1.2 生成器与return比较

  • 普通函数使用return返回结果后,其执行状态就会被销毁。
  • 生成器使用yield关键字,在返回值的同时会保存当前执行状态,下次调用时可以从上次暂停的地方继续执行。

      通俗的说,yield就是和return一样执行到该位置时返回变量值,但函数不会结束退出,而是暂停在这个位置挂起任务,等待下一次next()调用时,从暂停的位置继续执行。

二、创建生成器

方法1: 生成器函数

使用yield关键字代替return的函数就是生成器函数:

def simple_generator():yield 1yield 2yield 3# 使用生成器
gen = simple_generator()
print(next(gen))  # 输出: 1
print(next(gen))  # 输出: 2
print(next(gen))  # 输出: 3

方法2: 生成器表达式

类似列表推导式,但使用圆括号:

# 列表推导式 - 立即计算所有值
squares_list = [x*x for x in range(5)]  # [0, 1, 4, 9, 16]# 生成器表达式 - 按需生成值
squares_gen = (x*x for x in range(5))
print(next(squares_gen))  # 输出: 0
print(next(squares_gen))  # 输出: 1

三、生成器的实际应用场景

3.1 处理大型文件

def read_large_file(file_path):"""逐行读取大文件,避免内存溢出"""with open(file_path, 'r') as file:for line in file:yield line.strip()# 使用生成器处理GB级文件
for line in read_large_file('huge_file.txt'):process_line(line)  # 每次只处理一行,不占用大量内存

3.2 生成无限序列

def fibonacci():"""生成无限斐波那契数列"""a, b = 0, 1while True:yield aa, b = b, a + b# 获取前10个斐波那契数
fib_gen = fibonacci()
first_10 = [next(fib_gen) for _ in range(10)]
print(first_10)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

3.3 数据管道处理

def numbers():for i in range(10):yield idef square(nums):for num in nums:yield num ** 2def even_filter(nums):for num in nums:if num % 2 == 0:yield num# 构建数据处理管道
result = even_filter(square(numbers()))
print(list(result))  # [0, 4, 16, 36, 64]

四、生成器的高级用法

4.1 使用send()方法传递值

def generator_with_send():value = yield "开始"while True:value = yield f"收到: {value}"gen = generator_with_send()
print(next(gen))      # 输出: "开始"
print(gen.send("你好"))  # 输出: "收到: 你好"
print(gen.send("世界"))  # 输出: "收到: 世界"

4.2 生成器委托(yield from)

def sub_generator():yield from range(3)yield from ['a', 'b', 'c']for item in sub_generator():print(item)  # 输出: 0, 1, 2, 'a', 'b', 'c'

五、生成器的特点

优势:

  • 内存效率:一次只产生一个值,不占用大量内存

  • 惰性计算:需要时才计算,避免不必要的运算

  • 代码简洁:用简洁的语法表达复杂的迭代逻辑

  • 流水线处理:可以构建高效的数据处理管道

缺点:

  • 生成器只能迭代一次,迭代完后需要重新创建

  • 不适合需要随机访问的场景

  • 调试可能比普通函数复杂

总结

        生成器是Python中强大而高效的工具,特别适合处理大数据流、构建数据处理管道和创建无限序列。通过掌握生成器,你可以编写出更加内存友好和Pythonic的代码。

http://www.xdnf.cn/news/18941.html

相关文章:

  • 数据结构01:顺序表
  • 次元小镇官网入口 - 二次元动漫社区|COS绘画插画壁纸分享
  • [数据结构] ArrayList与顺序表(下)
  • STM32——PWR
  • 机器视觉学习-day06-图像旋转
  • KafKa学习笔记
  • 【Day 35】Linux-Mysql错误总结
  • DA14531(Cortex-M0+)之Wake-up Interrupt Controller (WIC)
  • React学习教程,从入门到精通, ReactJS - 安装:初学者指南(3)
  • linux 网络:并发服务器及IO多路复用
  • 如何将yolo训练图像数据库的某个分类的图像取出来
  • element-plus的el-scrollbar显示横向滚动条
  • 使用华为 USG6000防火墙配置安全策略
  • 传输层协议介绍
  • 企业通讯软件以安全为基,搭建高效的通讯办公平台
  • Python篇---返回类型
  • 【论文阅读】PEPNet
  • amis上传组件导入文件接口参数为base64格式的使用示例
  • 计算机三级嵌入式填空题——真题库(22)原题附答案速记
  • 强化学习与注意力机制的AlignSAM框架解析
  • 微算法科技(NASDAQ:MLGO)推出创新型混合区块链共识算法,助力物联网多接入边缘计算
  • [n8n] 工作流数据库管理SQLite | 数据访问层-REST API服务
  • Paimon——官网阅读:Flink 引擎
  • 前端javascript在线生成excel,word模板-通用场景(免费)
  • AbMole小课堂丨详解野百合碱在动物肺动脉高压、急性肺损伤、静脉闭塞肝病造模中的原理及应用
  • Go 语言常用命令使用与总结
  • 微信小程序对接EdgeX Foundry详细指南
  • 云计算学习100天-第31天
  • 从零开始的云计算生活——第五十三天,发愤图强,kubernetes模块之Prometheus和发布
  • 【SpringAI】快速上手,详解项目快速集成主流大模型DeepSeek,ChatGPT