推导式 #

推导式(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