全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 6 分钟 ✍️ juanwangdev

Python 生成器表达式

生成器表达式是创建轻量级迭代器的简洁语法,类似列表推导式但使用圆括号。

基本语法

Python
# 列表推导式:立即生成全部元素
lst = [x * 2 for x in range(5)]
print(lst)  # [0, 2, 4, 6, 8]

# 生成器表达式:惰性生成
gen = (x * 2 for x in range(5))
print(gen)  # <generator object>
print(list(gen))  # [0, 2, 4, 6, 8]

与列表推导式对比

Python
import sys

# 列表:预分配内存
lst = [x for x in range(10000)]
print(sys.getsizeof(lst))  # 约 87624 bytes

# 生成器:几乎不占内存
gen = (x for x in range(10000))
print(sys.getsizeof(gen))  # 约 112 bytes
特性列表推导式生成器表达式
括号[]()
内存立即占用惰性生成
可迭代多次一次
索引访问支持不支持
适用场景需要全部元素流式处理

惰性求值

Python
# 列表推导式:立即执行所有计算
results = [x ** 2 for x in range(1000000)]  # 立即计算全部

# 生成器表达式:按需计算
results_gen = (x ** 2 for x in range(1000000))
print(next(results_gen))  # 0(只计算第一个)

带条件过滤

Python
# 过滤偶数
evens = (x for x in range(20) if x % 2 == 0)
print(list(evens))  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 多条件
filtered = (x for x in range(20) if x > 5 and x % 2 == 0)
print(list(filtered))  # [6, 8, 10, 12, 14, 16, 18]

嵌套循环

Python
# 生成坐标对
coords = ((x, y) for x in range(3) for y in range(3))
print(list(coords))
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

# 嵌套条件
pairs = ((x, y) for x in range(5) if x > 2 for y in range(5) if y < x)
print(list(pairs))
# [(3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (4, 3)]

函数参数中的生成器表达式

在函数参数中,圆括号可省略:

Python
# 等价写法
sum((x for x in range(10)))  # 45
sum(x for x in range(10))    # 45(省略括号)

max(x ** 2 for x in range(10))  # 81
min(x for x in [-1, 0, 1])      # -1

# 生成器作为参数,避免创建中间列表
total = sum(x * 2 for x in range(1000000))  # 高效
# 而非 total = sum([x * 2 for x in range(1000000)])  # 低效

链式操作

生成器表达式可与其他迭代工具组合:

Python
from itertools import islice, takewhile

# 切片
gen = (x ** 2 for x in range(100))
print(list(islice(gen, 5)))  # [0, 1, 4, 9, 16]

# 条件取值
gen = (x for x in range(20))
result = list(takewhile(lambda x: x < 5, gen))
print(result)  # [0, 1, 2, 3, 4]

# 多阶段管道
data = range(100)
stage1 = (x * 2 for x in data)      # 加倍
stage2 = (x for x in stage1 if x > 50)  # 过滤
stage3 = (x / 10 for x in stage2)       # 除以10
print(list(stage3))  # [5.2, 5.4, 5.6, ..., 19.8]

实际应用

处理大文件

Python
# 读取文件行(惰性)
lines = (line.strip() for line in open('large.txt'))

# 过滤空行
non_empty = (line for line in lines if line)

# 提取数据
data = (parse_line(line) for line in non_empty)

# 流式处理,不一次性加载全部内容
for item in data:
    process(item)

数据转换管道

Python
# 多步转换
raw_data = [1, -2, 3, -4, 5]

# 过滤 → 转换 → 格式化
pipeline = (
    f"value: {x}"
    for x in (abs(x) for x in raw_data)
    if x > 2
)

print(list(pipeline))  # ['value: 3', 'value: 4', 'value: 5']

聚合计算

Python
# 计算平均值(不创建中间列表)
data = range(1000000)
avg = sum(x for x in data) / len(data)

# 条件聚合
total = sum(x for x in range(100) if x % 3 == 0)
print(total)  # 1683

注意事项

一次性消耗

Python
gen = (x for x in range(5))
print(list(gen))  # [0, 1, 2, 3, 4]
print(list(gen))  # [](已耗尽)

不支持索引

Python
gen = (x for x in range(5))
# gen[0]  # TypeError: 不支持索引

# 必须转换为列表才能索引
lst = list(gen)
print(lst[0])  # 0

不能切片

Python
gen = (x for x in range(10))
# gen[2:5]  # TypeError

# 使用 islice
from itertools import islice
print(list(islice(gen, 2, 5)))  # [2, 3, 4]

转换为其他类型

Python
gen = (x for x in range(5))

# 转列表
lst = list(gen)       # [0, 1, 2, 3, 4]

# 转元组
gen = (x for x in range(5))
tup = tuple(gen)      # (0, 1, 2, 3, 4)

# 转集合
gen = (x % 3 for x in range(10))
s = set(gen)          # {0, 1, 2}

与生成器函数等价

Python
# 生成器表达式
gen_expr = (x ** 2 for x in range(5))

# 等价的生成器函数
def gen_func():
    for x in range(5):
        yield x ** 2

# 两者效果相同
print(list(gen_expr))     # [0, 1, 4, 9, 16]
print(list(gen_func()))   # [0, 1, 4, 9, 16]

要点总结

特性说明
语法(expression for item in iterable if condition)
括号函数参数中可省略
惰性按需生成,节省内存
一次性只能迭代一次
组合可与 itertools 链式组合

生成器表达式适合简单迭代场景,复杂逻辑优先使用生成器函数。

D:\git2\jwdev\articles\PYTHON\进阶\迭代器与生成器\生成器表达式.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python 生成器函数
下一篇 → Python 自定义迭代器类
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库