推导式 #
推导式(Comprehension)是Python的一种简洁语法,用于创建序列。
一、列表推导式 #
1.1 基本语法 #
python
# 基本语法:[表达式 for 变量 in 可迭代对象]
squares = [x ** 2 for x in range(5)]
print(squares) # [0, 1, 4, 9, 16]
# 等价于传统循环
squares = []
for x in range(5):
squares.append(x ** 2)
1.2 带条件过滤 #
python
# 语法:[表达式 for 变量 in 可迭代对象 if 条件]
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
# 过滤负数
numbers = [-2, -1, 0, 1, 2]
positives = [x for x in numbers if x > 0]
print(positives) # [1, 2]
# 等价于传统循环
positives = []
for x in numbers:
if x > 0:
positives.append(x)
1.3 带条件表达式 #
python
# 语法:[值1 if 条件 else 值2 for 变量 in 可迭代对象]
numbers = [-2, -1, 0, 1, 2]
labels = ["负数" if x < 0 else "非负数" for x in numbers]
print(labels) # ['负数', '负数', '非负数', '非负数', '非负数']
# 绝对值
abs_values = [x if x >= 0 else -x for x in numbers]
print(abs_values) # [2, 1, 0, 1, 2]
1.4 嵌套循环 #
python
# 嵌套循环
pairs = [(x, y) for x in range(3) for y in range(3)]
print(pairs)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 等价于
pairs = []
for x in range(3):
for y in range(3):
pairs.append((x, y))
# 展平嵌套列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 带条件的嵌套
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]
print(pairs) # [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
1.5 实用示例 #
python
# 字符串处理
words = ["Hello", "World", "Python"]
lower_words = [w.lower() for w in words]
print(lower_words) # ['hello', 'world', 'python']
# 提取属性
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
people = [Person("Tom", 25), Person("Jerry", 30)]
names = [p.name for p in people]
print(names) # ['Tom', 'Jerry']
# 文件读取
lines = [line.strip() for line in open('data.txt')]
# 过滤空行
lines = [line for line in open('data.txt') if line.strip()]
二、字典推导式 #
2.1 基本语法 #
python
# 语法:{键表达式: 值表达式 for 变量 in 可迭代对象}
squares = {x: x ** 2 for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 字符串长度
words = ["hello", "world", "python"]
word_lengths = {word: len(word) for word in words}
print(word_lengths) # {'hello': 5, 'world': 5, 'python': 6}
2.2 带条件 #
python
# 过滤
scores = {'Tom': 85, 'Jerry': 60, 'Alice': 90, 'Bob': 45}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed) # {'Tom': 85, 'Jerry': 60, 'Alice': 90}
2.3 键值互换 #
python
# 键值互换
original = {'a': 1, 'b': 2, 'c': 3}
swapped = {v: k for k, v in original.items()}
print(swapped) # {1: 'a', 2: 'b', 3: 'c'}
2.4 分组 #
python
# 按条件分组
words = ['apple', 'banana', 'cherry', 'date', 'elderberry']
grouped = {}
for word in words:
key = len(word)
if key not in grouped:
grouped[key] = []
grouped[key].append(word)
print(grouped) # {5: ['apple'], 6: ['banana', 'cherry', 'date'], 9: ['elderberry']}
# 使用defaultdict
from collections import defaultdict
grouped = defaultdict(list)
for word in words:
grouped[len(word)].append(word)
2.5 从两个列表创建字典 #
python
keys = ['name', 'age', 'city']
values = ['Tom', 25, 'Beijing']
# 使用zip
person = {k: v for k, v in zip(keys, values)}
print(person) # {'name': 'Tom', 'age': 25, 'city': 'Beijing'}
# 或直接使用dict
person = dict(zip(keys, values))
三、集合推导式 #
3.1 基本语法 #
python
# 语法:{表达式 for 变量 in 可迭代对象}
squares = {x ** 2 for x in range(-3, 4)}
print(squares) # {0, 1, 4, 9}(自动去重)
# 字符串唯一字符
text = "hello world"
unique_chars = {char for char in text if char != ' '}
print(unique_chars) # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}
3.2 带条件 #
python
# 过滤
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_evens = {x for x in numbers if x % 2 == 0}
print(unique_evens) # {2, 4}
3.3 实用示例 #
python
# 获取文件扩展名
files = ['script.py', 'data.json', 'test.py', 'config.yaml']
extensions = {f.split('.')[-1] for f in files}
print(extensions) # {'py', 'json', 'yaml'}
# 提取单词首字母
words = ['apple', 'banana', 'cherry']
first_letters = {word[0] for word in words}
print(first_letters) # {'a', 'b', 'c'}
四、生成器表达式 #
4.1 基本语法 #
python
# 语法:(表达式 for 变量 in 可迭代对象)
squares = (x ** 2 for x in range(5))
print(squares) # <generator object at ...>
print(list(squares)) # [0, 1, 4, 9, 16]
# 注意:生成器只能迭代一次
squares = (x ** 2 for x in range(5))
print(sum(squares)) # 30
print(sum(squares)) # 0(已经迭代完了)
4.2 内存效率 #
python
# 列表推导式:立即创建所有元素
squares_list = [x ** 2 for x in range(1000000)] # 占用大量内存
# 生成器表达式:惰性计算
squares_gen = (x ** 2 for x in range(1000000)) # 几乎不占内存
# 在函数参数中使用
total = sum(x ** 2 for x in range(1000000))
4.3 带条件 #
python
# 过滤
evens = (x for x in range(10) if x % 2 == 0)
print(list(evens)) # [0, 2, 4, 6, 8]
# 链式处理
result = (x * 2 for x in range(5) if x % 2 == 0)
print(list(result)) # [0, 4, 8]
4.4 作为函数参数 #
python
# 直接作为函数参数
total = sum(x ** 2 for x in range(10))
print(total) # 285
max_value = max(x for x in range(10))
print(max_value) # 9
# any/all
has_even = any(x % 2 == 0 for x in [1, 3, 5, 7, 9])
print(has_even) # False
all_positive = all(x > 0 for x in [1, 2, 3, 4, 5])
print(all_positive) # True
# join
words = ['hello', 'world']
result = ' '.join(word.upper() for word in words)
print(result) # 'HELLO WORLD'
五、推导式对比 #
| 类型 | 语法 | 结果类型 |
|---|---|---|
| 列表推导式 | [x for x in iter] |
列表 |
| 字典推导式 | {k: v for k, v in iter} |
字典 |
| 集合推导式 | {x for x in iter} |
集合 |
| 生成器表达式 | (x for x in iter) |
生成器 |
python
# 对比
data = range(5)
list_comp = [x ** 2 for x in data] # [0, 1, 4, 9, 16]
dict_comp = {x: x ** 2 for x in data} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
set_comp = {x % 3 for x in data} # {0, 1, 2}
gen_expr = (x ** 2 for x in data) # 生成器对象
六、性能考虑 #
6.1 列表推导式 vs 传统循环 #
python
import time
# 列表推导式通常更快
def test_list_comp():
return [x ** 2 for x in range(10000)]
def test_traditional():
result = []
for x in range(10000):
result.append(x ** 2)
return result
# 列表推导式更快,因为:
# 1. 减少函数调用开销
# 2. 使用优化的C代码
6.2 生成器 vs 列表 #
python
# 大数据量时使用生成器
# 列表:立即占用所有内存
big_list = [x for x in range(10000000)] # ~80MB
# 生成器:几乎不占内存
big_gen = (x for x in range(10000000)) # 几乎0MB
# 但如果需要多次迭代,列表更合适
6.3 复杂表达式 #
python
# 复杂表达式:可读性优先
# 不推荐:过于复杂的推导式
result = [process(item) for sublist in data
if condition(sublist)
for item in sublist
if item is not None
for key, value in item.items()
if value > 0]
# 推荐:使用传统循环
result = []
for sublist in data:
if not condition(sublist):
continue
for item in sublist:
if item is None:
continue
for key, value in item.items():
if value > 0:
result.append(process(item))
七、嵌套推导式 #
7.1 嵌套列表推导式 #
python
# 创建矩阵
matrix = [[i * j for j in range(5)] for i in range(5)]
print(matrix)
# [[0, 0, 0, 0, 0],
# [0, 1, 2, 3, 4],
# [0, 2, 4, 6, 8],
# [0, 3, 6, 9, 12],
# [0, 4, 8, 12, 16]]
# 转置矩阵
transposed = [[row[i] for row in matrix] for i in range(5)]
# 使用zip更简洁
transposed = list(zip(*matrix))
7.2 三维列表 #
python
# 三维列表
cube = [[[i + j + k for k in range(3)]
for j in range(3)]
for i in range(3)]
八、常见陷阱 #
8.1 变量作用域 #
python
# Python 3中,推导式有自己的作用域
x = 10
result = [x for x in range(3)]
print(x) # 10(外部的x没有被修改)
# 但嵌套推导式共享变量
result = [[j for j in range(3)] for i in range(3)]
8.2 可变对象 #
python
# 共享引用问题
matrix = [[0] * 3] * 3 # 三行共享同一列表
matrix[0][0] = 1
print(matrix) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
# 正确方式
matrix = [[0] * 3 for _ in range(3)] # 每行独立的列表
matrix[0][0] = 1
print(matrix) # [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
8.3 过于复杂 #
python
# 不推荐:过于复杂
result = [f(x) for x in xs if condition(x) for y in ys if g(x, y)]
# 推荐:拆分
filtered = [x for x in xs if condition(x)]
result = [f(x) for x in filtered for y in ys if g(x, y)]
九、总结 #
| 推导式类型 | 用途 | 返回类型 |
|---|---|---|
| 列表推导式 | 创建列表 | list |
| 字典推导式 | 创建字典 | dict |
| 集合推导式 | 创建集合(去重) | set |
| 生成器表达式 | 惰性计算 | generator |
最佳实践:
- 简单转换和过滤:使用推导式
- 复杂逻辑:使用传统循环
- 大数据量:使用生成器表达式
- 需要多次迭代:使用列表
- 保持可读性:不要过度嵌套
最后更新:2026-03-16