Python 生成器表达式
Summary
生成器表达式用类似列表推导式的语法创建生成器对象,惰性计算,逐个产出,不会一次性生成完整列表。
一、列表推导式 vs 生成器表达式
| 特性 | 列表推导式 [...] | 生成器表达式 (...) |
|---|---|---|
| 语法 | [x for x in iterable] | (x for x in iterable) |
| 返回值 | list(完整列表) | generator(生成器对象) |
| 内存占用 | 一次性存储所有元素 | 惰性计算,逐个产出 |
| 遍历次数 | 可多次遍历 | 只能遍历一次(耗尽后为空) |
| 访问方式 | 支持索引 lst[0] | 不支持索引,只能迭代 |
# 列表推导式 —— 立即计算,占用内存
squares_list = [x**2 for x in range(1000000)] # 内存中存100万个整数
# 生成器表达式 —— 惰性计算,几乎不占内存
squares_gen = (x**2 for x in range(1000000)) # 只是一个生成器对象
二、使用情形
- 迭代遍历(最常用): 迭代完后消失,阅后即焚
gen = (x**2 for x in range(5))
for val in gen:
print(val) # 0, 1, 4, 9, 16
# 再次遍历为空(已耗尽)
for val in gen:
print(val) # 无输出
- 用
next()逐个获取:说明这是个迭代器
gen = (x for x in "abc")
print(next(gen)) # 'a'
print(next(gen)) # 'b'
print(next(gen)) # 'c'
print(next(gen)) # StopIteration 异常
- 转换为其他类型(会立即计算):强制类型转换时精度扩展
gen = (x*2 for x in range(5))
list(gen) # [0, 2, 4, 6, 8]
tuple(gen) # () —— 已耗尽,为空
set(gen) # set() —— 已耗尽
三、总结
- 惰性求值:元素在需要时才生成,节省内存
- 一次性:遍历后即耗尽,不能重复使用
- 无索引:不支持随机访问,只能顺序迭代
- 括号规则:
- 单参数函数调用时外层括号可省略:
sum(x for x in range(10)) - 多参数时必须加括号:
func(a, (x for x in b), c)
- 单参数函数调用时外层括号可省略: