在 Python 中,推导式(Comprehension) 是一种简洁且高效的创建数据结构(列表、字典、集合)的语法。它允许你在一行代码内生成序列,替代传统的循环结构,使代码更易读、更优雅。
一、列表推导式(List Comprehension)
基本语法
python
[表达式 for 变量 in 可迭代对象]
示例:生成平方数列表
python
squares = [x**2 for x in range(5)]
print(squares) # 输出: [0, 1, 4, 9, 16]
带条件过滤
python
[表达式 for 变量 in 可迭代对象 if 条件]
示例:过滤偶数
python
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # 输出: [0, 2, 4, 6, 8]
嵌套循环
python
[表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]
示例:合并两个列表元素
python
pairs = [(x, y) for x in [1, 2] for y in [3, 4]]
print(pairs) # 输出: [(1, 3), (1, 4), (2, 3), (2, 4)]
二、字典推导式(Dict Comprehension)
基本语法
python
{键表达式: 值表达式 for 变量 in 可迭代对象}
示例:交换字典的键和值
python
original = {'a': 1, 'b': 2}
swapped = {v: k for k, v in original.items()}
print(swapped) # 输出: {1: 'a', 2: 'b'}
带条件过滤
python
{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}
示例:过滤值大于 1 的项
python
filtered = {k: v for k, v in original.items() if v > 1}
print(filtered) # 输出: {'b': 2}
三、集合推导式(Set Comprehension)
基本语法
python
{表达式 for 变量 in 可迭代对象}
示例:生成去重后的平方数集合
python
squares_set = {x**2 for x in [1, 2, 2, 3]}
print(squares_set) # 输出: {1, 4, 9}
带条件过滤
python
{表达式 for 变量 in 可迭代对象 if 条件}
示例:生成偶数的平方集合
python
evens_squares = {x**2 for x in range(5) if x % 2 == 0}
print(evens_squares) # 输出: {0, 4, 16}
四、生成器表达式(Generator Expression)
基本语法
python
(表达式 for 变量 in 可迭代对象)
示例:惰性生成平方数
python
gen = (x**2 for x in range(3))
print(next(gen)) # 输出: 0
print(next(gen)) # 输出: 1
与列表推导式的区别
- 列表推导式:立即生成完整列表,占用内存。
- 生成器表达式:惰性生成元素,节省内存,适合大数据处理。
五、使用技巧
1. 条件表达式
python
[表达式1 if 条件 else 表达式2 for 变量 in 可迭代对象]
示例:将负数转换为 0,正数保留
python
nums = [-1, 2, -3, 4]
result = [x if x >= 0 else 0 for x in nums]
print(result) # 输出: [0, 2, 0, 4]
2. 嵌套推导式
示例:展平二维列表
python
matrix = [[1, 2], [3, 4]]
flattened = [x for row in matrix for x in row]
print(flattened) # 输出: [1, 2, 3, 4]
六、性能对比
推导式通常比传统循环更高效,尤其是处理大数据时。例如:
python
# 列表推导式 vs 传统循环
squares1 = [x**2 for x in range(1000)] # 更快
squares2 = []
for x in range(1000):
squares2.append(x**2) # 稍慢
七、总结
类型 | 语法 | 返回类型 | 是否惰性 |
---|---|---|---|
列表推导式 | [表达式 for ...] | 列表 | 否 |
字典推导式 | {键:值 for ...} | 字典 | 否 |
集合推导式 | {表达式 for ...} | 集合 | 否 |
生成器表达式 | (表达式 for ...) | 生成器 | 是 |
优点:代码简洁、执行速度快。
缺点:过度复杂的推导式会降低可读性。建议保持逻辑简单,必要时拆分多行。
分享
列表推导式和其他创建列表的方式相比,有哪些优势?
推导式可以用于集合和字典吗?如何使用?
推导式中的表达式可以是复杂的函数调用吗?