首页 / Python3 入门教程 / 推导式与生成器表达式

Python3 入门教程

推导式与生成器表达式

本教程共 70 篇 · 第 20 篇 · 更新于 2026-07-22 · 约 2 分钟阅读

PythonPython3 入门教程列表推导式字典推导式生成器表达式惰性求值

20. 推导式与生成器表达式

本节目标:掌握列表、字典、集合推导式和生成器表达式,用简洁的语法高效创建数据结构。

列表推导式

列表推导式是把一个循环压缩成一行的语法糖:

# 传统写法
squares = []
for x in range(10):
    squares.append(x ** 2)

# 推导式写法
squares = [x ** 2 for x in range(10)]

可读性不下降,代码更紧凑。

带条件的列表推导式

# 只保留偶数的平方
evens = [x ** 2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]

# 多重条件
result = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
# [0, 15, 30, 45, 60, 75, 90]

多层循环的推导式

>>> [(x, y) for x in [1, 2] for y in ['a', 'b']]
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

等价于:

result = []
for x in [1, 2]:
    for y in ['a', 'b']:
        result.append((x, y))
Warning

推导式嵌套超过两层就很难读了。复杂逻辑还是展开成普通循环。

带 else 的推导式

条件表达式可以放在前面:

# 奇数保留原值,偶数变为其一半
result = [x if x % 2 else x // 2 for x in range(10)]
# [0, 1, 1, 3, 2, 5, 3, 7, 4, 9]
Note

这里的 if 不是过滤,而是条件表达式(三元表达式),每个元素都会生成一个结果。

字典推导式

# 数字到平方的映射
>>> {x: x**2 for x in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 从已有字典筛选
>>> prices = {"apple": 3, "banana": 2, "cherry": 8}
>>> {k: v for k, v in prices.items() if v > 2}
{'apple': 3, 'cherry': 8}

# 交换键值(值必须可哈希)
>>> {v: k for k, v in {"a": 1, "b": 2}.items()}
{1: 'a', 2: 'b'}

# 用两个列表创建字典
>>> names = ["Alice", "Bob"]
>>> ages = [25, 30]
>>> {name: age for name, age in zip(names, ages)}
{'Alice': 25, 'Bob': 30}

集合推导式

>>> {x**2 for x in range(10)}
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}

>>> {x for x in 'abracadabra' if x not in 'abc'}
{'d', 'r'}

集合推导式自动去重,适合需要唯一结果的场景。

生成器表达式

把列表推导式的方括号 [] 换成圆括号 (),就得到生成器表达式

>>> gen = (x ** 2 for x in range(10))
>>> gen
<generator object <genexpr> at 0x...>

生成器表达式不会立即计算所有结果,而是惰性求值——你问它要一个,它算一个。

>>> next(gen)
0
>>> next(gen)
1
>>> sum(x ** 2 for x in range(10))   # 括号可以省略
285
Tip

如果只是遍历一次,不需要存下所有结果,用生成器表达式比列表推导式更省内存。

# 列表推导式:创建包含 1000 万个整数的列表,可能占用几百 MB
total = sum([x ** 2 for x in range(10_000_000)])

# 生成器表达式:不存列表,算一个加一个
total = sum(x ** 2 for x in range(10_000_000))

推导式 vs 生成器:怎么选

场景推荐
需要反复访问、随机索引列表推导式 []
只遍历一次、数据量大生成器表达式 ()
需要键值对查找字典推导式 {}
需要去重集合推导式 {}
Note

元组没有推导式。(x for x in range(5)) 是生成器表达式,不是元组推导式。需要元组时,用 tuple(x for x in range(5)) 把生成器转成元组。

一个实用技巧:扁平化列表

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

注意循环顺序:跟普通嵌套循环一样,外层循环写前面,内层写后面。


来源:参考了 runoob「Python 推导式」、liaoxuefeng「列表生成式」等,改写后所得。