惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
爱范儿
爱范儿
The Cloudflare Blog
腾讯CDC
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
云风的 BLOG
云风的 BLOG
Recent Announcements
Recent Announcements
C
Check Point Blog
Schneier on Security
Schneier on Security
S
Schneier on Security
J
Java Code Geeks
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
About on SuperTechFans
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
A
Arctic Wolf
S
Secure Thoughts
P
Palo Alto Networks Blog
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security
量子位
U
Unit 42
I
InfoQ
D
DataBreaches.Net
P
Privacy International News Feed
T
Troy Hunt's Blog
博客园 - 叶小钗
T
Threatpost
博客园 - Franky
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cisco Blogs

博客园 - 箫笛

Tkinter - Button 组件 Tkinter - Label 组件 Tkinter - tk 变量 Tkinter - 事件与绑定 Tkinter - 几何管理器 Tkinter - 核心概念 Tkinter - 快速开始 Tkinter - 介绍 Python 编程 - 条件表达式 Python 编程 - 星号下划线参数释义 shell 编程 - shell 脚本的交互方式 Python insall - macOS 系统安装python的几种方式 Miniconda - Python 环境管理工具 Tkinter - Python GUI 开发 Python 编程 - 下划线命名的区别 Python 编程 - 元类编程 Python 编程 - 多重继承与MRO Python 编程 - 描述符协议 Python 编程 - 类型注解 Python 编程 - 集合 Python 编程 - 装饰器 Python 编程 - 闭包 Python 编程 - 列表推导式 Python 编程 - 函数式编程 Python 编程 - lambda 函数 Python 编程 - 文件操作 Python 编程 - 输入与输出 Python 编程 - 面向对象编程 Python 编程 - 元组(tuple) Python 编程 - 字符串(str) Python 编程 - 字典(dict) Python 编程 - 列表(list) Python 编程 - 数据类型和数据结构 Python 编程 - 语句 Python 编程 - 函数 windows - WSL 的安装与使用 shell编程 - dialog 程序使用指南 FE Team - 如何做好前端代码审查 git 提交的撤销和恢复 React15 - redux-saga 如何在saga中实现轮询接口调用? React15 - React CSS Modules BEM命名实践 React15 - React 15 中 componentWillReceiveProps 为什么会多次调用, 同时componentDidUpdate 也会多次调用? React15 - React15类组件多次执行render方法的原因? React15 - React15应用中代码逻辑复用方案 React15 - React状态同步问题解决 React15 - React 15 中 React.pureComponent 的使用场景 React15 - React 15应用在页面渲染时会多次执行类组件的render 函数的原因 React15 - React 15 中能用 componetDidUpdate 代替 componentWillReceiveProps 吗? React15 - React 15 生命周期函数详解 React15 - 如何在React 15中实现自定义的事件订阅与发送(例如组件间通信) React15 - React15应用中的事件订阅和发送机制 React15 - CSS中的BEM规范 React15 - React CSS Modules BEM命名实践 React15 - 写sass 样式文件,嵌套的结构好,还是扁平的结构好? React15 - sass 中 @mixin 和 @extend 的区别是什么? React15 - React 15 应用 如何使用Css moudules 方式进行模块化开发 React15 - React15应用Sass使用指南 React15 - React 15 应用如何进行性能优化?
Python 编程 - 生成器表达式
箫笛 · 2026-06-25 · via 博客园 - 箫笛

生成器表达式(Generator Expression) 是 Python 3 中一种内存效率极高的迭代器创建方式。它外观类似列表推导式,但使用圆括号 (),核心区别在于惰性求值(Lazy Evaluation)——边迭代边生成值,不会一次性将所有数据加载到内存。

1. 基本语法

(expression for item in iterable if condition)

对比列表推导式:

# 列表推导式(立即生成所有数据,占用内存)
list_comp = [x**2 for x in range(1000)]  # 占用 ~8KB 以上

# 生成器表达式(惰性生成,只记录算法)
gen_exp = (x**2 for x in range(1000))    # 占用 ~几百字节

2. 核心特性与使用

生成器表达式返回一个 生成器对象,它既是迭代器也是可迭代对象。

基础遍历:

gen = (i * 2 for i in range(5))
for val in gen:
    print(val, end=" ")  # 输出: 0 2 4 6 8

手动获取值(使用 next()):

gen = (i for i in range(3))
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 2
# print(next(gen))  # 抛出 StopIteration 异常

3. 高级应用与最佳实践

(1) 函数调用中省略多余括号

当生成器表达式作为唯一参数传入函数时,可以省略外层的圆括号,写法更简洁:

# 计算 1 到 1亿 的平方和(内存占用极低)
sum_of_squares = sum(x*x for x in range(100_000_000))
# 而不是 sum((x*x for x in range(...))) 

(2) 构建数据管道(流式处理)

生成器可以串联,处理超大文件或无限序列:

# 处理超大日志文件,筛选含 'ERROR' 的行,并提取时间戳
lines = (line for line in open('huge_log.txt'))          # 流式读行
errors = (line for line in lines if 'ERROR' in line)     # 惰性筛选
timestamps = (line.split()[0] for line in errors)        # 惰性提取

for ts in timestamps:  # 逐条处理,内存只存当前行
    print(ts)

(3) 嵌套循环与笛卡尔积

# 生成坐标对 (0,0) (0,1) ... (2,3)
coords = ((x, y) for x in range(3) for y in range(4))

4. 关键陷阱与注意事项(务必留意)

特性 说明 示例
一次性消费 生成器只能遍历一次。遍历完后内部指针耗尽,再次遍历为空。 gen = (x for x in [1,2,3]); list(gen) # [1,2,3]; list(gen) # []
不存储索引 无法像列表那样通过下标 gen[0] 访问,也不支持 len() 只能顺序迭代。
延迟计算的副作用 如果依赖外部变量,变量值在迭代时才被读取,而非定义时。 i = 5; gen = (x+i for x in range(3)); i = 10; list(gen) # 输出 [10,11,12]
性能取舍 内存占用极低,但每次取值有计算开销。重复遍历多次时,列表推导式更快。 数据量小(< 1000)用列表;数据量大或无限流用生成器。

5. 生成器表达式 vs yield 函数

  • 生成器表达式:适合简单逻辑的单行惰性计算(如 (x*2 for x in seq))。
  • yield 生成器函数:适合复杂逻辑(含循环嵌套、分支判断、状态保持)。
# 等价表达
gen1 = (x**2 for x in range(3))

def gen2():
    for x in range(3):
        yield x**2

6. 总结速查

  • 语法( 结果 for 变量 in 可迭代对象 [if 条件] )
  • 核心优势:处理海量数据、流式IO时,内存占用极小。
  • 黄金法则:如果你只需要迭代一次,且数据量巨大,请使用生成器表达式;如果需要反复使用或随机访问,请使用列表推导式。