Python 生成器教程:高效处理数据流的利器

简介: 本教程参考https://dnuhf.cn详解Python生成器:通过`yield`实现惰性求值,显著节省内存、支持无限序列与流式处理;涵盖生成器函数/表达式、`send()`/`throw()`高级用法及分页查询、日志监听等实战案例,助你高效处理大数据。(239字)

在 Python 编程中,当我们需要处理大量数据或无限序列时,一次性将所有数据加载到内存中可能非常低效甚至不可能。生成器(Generators)提供了一种优雅的解决方案,它允许我们按需生成值,从而节省内存并提高性能。本教程将带你从零开始理解生成器,并通过实际示例掌握它的用法。

  1. 什么是生成器?
    生成器是一种特殊的迭代器,它使用 yield 语句来产生一系列值。与普通函数不同,生成器函数不会一次性返回所有结果,而是在每次调用时暂停并返回一个值,直到下一次迭代继续执行。

普通函数 vs. 生成器函数
python

普通函数:返回一个列表,占用内存

def squares(n):
result = []
for i in range(n):
result.append(i ** 2)
return result

生成器函数:使用 yield,逐个产生值

def squares_gen(n):
for i in range(n):
yield i ** 2
调用普通函数会立即计算所有值并返回列表;而调用生成器函数会返回一个生成器对象,可以迭代它来逐个获取值。

  1. 生成器的工作原理
    生成器函数遇到 yield 时会暂停执行,并将 yield 后的值返回给调用者。下次调用生成器的 next() 方法(或使用 next() 函数)时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 或函数结束。

python
def count_up_to(n):
i = 0
while i < n:
yield i
i += 1

创建生成器对象

gen = count_up_to(3)
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # 2

print(next(gen)) # 引发 StopIteration

  1. 生成器表达式
    生成器表达式类似于列表推导式,但使用圆括号而非方括号,它返回一个生成器对象,而不是列表。

python

列表推导式:立即生成所有值

squares_list = [x**2 for x in range(10)]

生成器表达式:惰性求值

squares_gen = (x**2 for x in range(10))

print(squares_list) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print(squares_gen) # at 0x...>

迭代生成器

for val in squares_gen:
print(val, end=' ') # 0 1 4 9 16 25 36 49 64 81
生成器表达式在只需要遍历一次数据时非常高效,因为它不会一次性占用大量内存。

  1. 为什么使用生成器?
    4.1 节省内存
    当处理大型数据集(如读取大文件、处理无限序列)时,生成器只保留当前值,而不是整个序列。

python

读取大文件时,逐行处理,避免将整个文件加载到内存

def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()

使用生成器逐行处理

for line in read_large_file('huge_log.txt'):
process(line) # 每次只处理一行
4.2 延迟计算
生成器支持惰性求值,仅在需要时才计算值,这在处理无限序列时特别有用。

python
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b

fib = fibonacci()
for _ in range(10):
print(next(fib), end=' ') # 0 1 1 2 3 5 8 13 21 34
4.3 代码简洁
使用生成器可以避免维护复杂的状态变量,使代码更易读。

  1. 生成器的高级用法
    5.1 与 send() 交互
    生成器不仅可以产生值,还可以接收外部传入的值,通过 send() 方法实现双向通信。

python
def echo():
while True:
received = yield
print(f"Received: {received}")

gen = echo()
next(gen) # 启动生成器,执行到第一个 yield
gen.send("Hello") # Received: Hello
gen.send("World") # Received: World
5.2 使用 throw() 和 close()
throw():在生成器内部引发异常

close():终止生成器

python
def my_gen():
try:
yield 1
yield 2
except GeneratorExit:
print("Generator closed")
except ValueError:
print("ValueError occurred")

g = my_gen()
print(next(g)) # 1
g.throw(ValueError) # 输出 "ValueError occurred"

生成器被终止

  1. 实际应用案例
    案例1:分页处理数据库查询
    当数据库查询结果集很大时,可以使用生成器按页加载数据。

python
def paginated_query(query, page_size=100):
offset = 0
while True:
page = execute_query(query + f" LIMIT {page_size} OFFSET {offset}")
if not page:
break
for row in page:
yield row
offset += page_size

使用

for record in paginated_query("SELECT * FROM large_table"):
process(record)
案例2:流式处理日志文件
实时解析日志文件,提取关键信息。

python
def tail_log(file_path):
import time
with open(file_path, 'r') as f:
f.seek(0, 2) # 移动到文件末尾
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
yield line.strip()

for line in tail_log('/var/log/syslog'):
if 'ERROR' in line:
print(line)

  1. 总结
    生成器是 Python 中处理数据流的强大工具,具有以下优点:

内存高效:无需一次性存储所有数据

惰性求值:仅在需要时计算

可组合性:可以轻松构建数据管道

代码清晰:简化迭代逻辑

掌握生成器后,你可以更优雅地处理大数据、无限序列和异步操作。现在,尝试用生成器改写你代码中的循环和列表推导,体验它的魅力吧!

练习:

写一个生成器,产生前 n 个素数。

使用生成器表达式计算 1 到 100 中偶数的平方和。

实现一个简单的协程,模拟一个计数器,可以接收递增步长。

提示:生成器是迭代器的一种,但迭代器不一定是生成器。理解 yield 关键字是掌握生成器的关键。

参考:http://dnuhf.cn/

相关文章
|
8天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
11046 92
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
8天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
4815 130
|
5天前
|
人工智能 自然语言处理 供应链
【最新】阿里云ClawHub Skill扫描:3万个AI Agent技能中的安全度量
阿里云扫描3万+AI Skill,发现AI检测引擎可识别80%+威胁,远高于传统引擎。
1324 3
|
6天前
|
人工智能 并行计算 Linux
本地私有化AI助手搭建指南:Ollama+Qwen3.5-27B+OpenClaw阿里云/本地部署流程
本文提供的全流程方案,从Ollama安装、Qwen3.5-27B部署,到OpenClaw全平台安装与模型对接,再到RTX 4090专属优化,覆盖了搭建过程的每一个关键环节,所有代码命令可直接复制执行。使用过程中,建议优先使用本地模型保障隐私,按需切换云端模型补充功能,同时注重显卡温度与显存占用监控,确保系统稳定运行。
1680 5
|
14天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
2855 6

热门文章

最新文章