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

【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.dtcms.com/a/356024.html

相关文章:

  • JDK的ConcurrentHashMap为什么放弃了分段锁
  • 大模型开发之:LangChain4j【附资料】
  • C++基础知识:虚函数和纯虚函数
  • 基于MATLAB的FIR滤波器设计与信号分离实现
  • 线性回归的法方程:原理与解析
  • 复习笔记11
  • 【K8s】整体认识K8s之pod
  • 【Git】Git 常用指令
  • 使用华为 USG6000防火墙配置安全策略
  • 今日行情明日机会——20250828
  • 驾驭巨量数据:HTTP 协议与大文件传输的多种策略
  • 【Python开源环境】Anaconda/Miniconda
  • 印度尼西亚数据源 PHP 对接文档
  • 从零搭建安全帽检测(8)— 泛化性检验:构建独立测试集与模型性能公正评估
  • 动态加载和异步调用tasklet/workqueue day63 ay64
  • 卷积神经网络搭建及应用
  • 对象之间属性拷贝(Bean Mapping)的工具MapStruct 和 BeanUtils
  • 多据点协作下的数据库权限与版本管理实战
  • BeforeEach与AfterEach注解的使用
  • React学习教程,从入门到精通, ReactJS - 安装:初学者指南(3)
  • iPhone17新品曝光!未来已来主题发布会即将登场
  • CSS入门学习
  • Vim 相关使用
  • Dify 从入门到精通(第 61/100 篇):Dify 的监控与日志分析(进阶篇)
  • 笔记本电脑蓝牙搜索不到设备-已解决
  • LoRA加入嵌入层、及输出头解析(63)
  • 实测阿里图像编辑模型Qwen-Image-Edit:汉字也能无痕修改(附实测案例)
  • 【 MYSQL | 基础篇 函数与约束 】
  • 响应式编程之Flow框架
  • cmd 中设置像 linux 一样设置别名(alias)