一、 前言
推导式(Comprehension)
是Python
中一种简洁、高效的数据结构构建方式,可以用更简洁的语法创建列表、字典、集合等数据结构。
二、列表推导式(List Comprehension
)
基本语法
[expression for item in iterable if condition]
基础示例
下面展示传统方式 与 推导式的不同,同样的结果,推导式更加简洁
# 传统方式
squares = []
for x in range(10):
squares.append(x**2)
# 列表推导式
squares = [x**2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
带条件的列表推导式
# 只保留偶数平方
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # [0, 4, 16, 36, 64]
# 使用条件表达式
numbers = [-1, 2, -3, 4, -5]
positive_numbers = [x if x > 0 else 0 for x in numbers]
print(positive_numbers) # [0, 2, 0, 4, 0]
嵌套循环
# 矩阵转置
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transpose = [[row[i] for row in matrix] for i in range(3)]
print(transpose) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
# 等价于
transpose = []
for i in range(3):
transpose.append([row[i] for row in matrix])
三、 字典推导式(Dictionary Comprehension
)
基本语法
{key_expression: value_expression for item in iterable if condition}
基础示例
# 创建数字到其平方的字典
squares_dict = {x: x**2 for x in range(6)}
print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 交换键值对
original_dict = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {v: k for k, v in original_dict.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
带条件的字典推导式
# 只保留值为奇数的项
original_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
odd_dict = {k: v for k, v in original_dict.items() if v % 2 != 0}
print(odd_dict) # {'a': 1, 'c': 3}
四、集合推导式(Set Comprehension
)
基本语法
{expression for item in iterable if condition}
基础示例
# 创建平方数的集合
squares_set = {x**2 for x in range(-5, 6)}
print(squares_set) # {0, 1, 4, 9, 16, 25}
# 去重并转换
words = ['hello', 'world', 'hello', 'python']
new_words = [it.upper() for it in set(words)]
print('=new_words==', new_words) # ['HELLO', 'WORLD', 'PYTHON']
五、元组-生成器表达式(Generator Expression
)
基本语法
(expression for item in iterable if condition)
基础示例
# 生成器表达式(惰性求值)
squares_gen = (x**2 for x in range(10))
print(squares_gen) # <generator object <genexpr> at 0x...>
# 使用生成器
for square in squares_gen:
print(square, end=' ') # 0 1 4 9 16 25 36 49 64 81
# 或者使用 tuple() 函数将生成器转化为元组
print('===squares_gen =', tuple(squares_gen )) # 0 1 4 9 16 25 36 49 64 81
# 生成器表达式作为函数参数
total = sum(x**2 for x in range(10))
print(total) # 285
六、实际应用案例
案例1:数据清洗
# 清洗数据:去除空值并转换为整数
raw_data = ['1', '2', '', '3', 'None', '4']
cleaned_data = [int(x) for x in raw_data if x and x != 'None']
print(cleaned_data) # [1, 2, 3, 4]
案例2:文本处理
# 统计单词长度分布
text = "Python is a powerful programming language"
word_lengths = {word: len(word) for word in text.split()}
print(word_lengths) # {'Python': 6, 'is': 2, 'a': 1, 'powerful': 8, 'programming': 11, 'language': 8}
案例3:矩阵操作
# 矩阵运算:每个元素乘以2
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
doubled = [[2 * element for element in row] for row in matrix]
print(doubled) # [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
案例4:配置文件解析
# 从环境变量创建配置字典
import os
# 模拟环境变量
os.environ['DB_HOST'] = 'localhost'
os.environ['DB_PORT'] = '9999'
config = {key[3:].lower(): value
for key, value in os.environ.items()
if key.startswith('DB_')}
print(config) # {'host': 'localhost', 'port': '5432'}
七、 注意事项和最佳实践
注意事项
可读性优先:过于复杂的推导式会降低代码可读性
避免副作用:推导式中不要包含有副作用的操作
内存考虑:列表推导式会立即创建整个列表,大数据集考虑使用生成器
最佳实践
# 不好的写法:过于复杂
result = [x**2 for x in [y for y in range(10) if y % 2 == 0] if x > 10]
# 好的写法:分步骤或使用传统循环
even_numbers = [y for y in range(10) if y % 2 == 0]
result = [x**2 for x in even_numbers if x > 10]
# 或者使用传统循环(当逻辑复杂时)
result = []
for y in range(10):
if y % 2 == 0:
x = y
if x > 10:
result.append(x**2)
性能考虑
import time
# 列表推导式 vs 生成器表达式
large_range = range(1000000)
# 列表推导式(立即计算,占用内存)
start = time.time()
list_comp = [x**2 for x in large_range]
end = time.time()
print(f"列表推导式时间: {end - start:.4f}秒")
# 生成器表达式(惰性计算,节省内存)
start = time.time()
gen_exp = (x**2 for x in large_range)
end = time.time()
print(f"生成器表达式创建时间: {end - start:.4f}秒")
八、 总结
推导式是Python中强大的特性,可以:
- 使代码更简洁、易读
- 提高开发效率
- 在某些情况下提高性能
但需要根据具体情况选择使用推导式还是传统循环,始终以代码可读性
和可维护性
为首要考虑因素。