目录
[2.1 列表推导式](#2.1 列表推导式)
[2.2 字典推导式](#2.2 字典推导式)
[2.3 集合推导式](#2.3 集合推导式)
[2.4 生成器表达式](#2.4 生成器表达式)
[3.1 嵌套推导式](#3.1 嵌套推导式)
[3.2 多重条件推导式](#3.2 多重条件推导式)
[4.1 性能比较](#4.1 性能比较)
[4.2 可读性比较](#4.2 可读性比较)
[5.1 数据清洗和转换](#5.1 数据清洗和转换)
[5.2 文件处理](#5.2 文件处理)
[5.3 API数据处理](#5.3 API数据处理)
一、推导式介绍
Python推导式(Comprehension)是一种简洁、优雅的语法结构,可以用单行代码快速创建列表、字典、集合等数据结构。它基于现有的可迭代对象,通过表达式和条件语句来生成新的数据集合。
不仅让代码更加简洁易读,而且在大多数情况下比传统的循环方式执行效率更高。
二、推导式的用法
Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。
Python 支持推导式的数据结构有:
- 列表(list)推导式
- 字典(dict)推导式
- 集合(set)推导式
- 元组(tuple)推导式
2.1 列表推导式
列表推导式是最常见的形式,用于创建新的列表。
基本语法:
python
[expression for item in iterable if condition]
示例:
python
# 传统方式
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]
带条件的列表推导式:
python
# 只保留偶数平方
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # [0, 4, 16, 36, 64]
# 使用条件表达式
results = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
print(results) # ['偶数', '奇数', '偶数', '奇数', '偶数']
嵌套循环的列表推导式:
python
# 生成所有可能的坐标对
coordinates = [(x, y) for x in range(3) for y in range(3)]
print(coordinates) # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
2.2 字典推导式
字典推导式用于创建字典,语法与列表推导式类似。
基本语法:
python
{key_expression: value_expression for item in iterable if condition}
示例:
python
# 创建数字到其平方的映射
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 反转字典的键和值
original = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {v: k for k, v in original.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
# 带条件的字典推导式
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
2.3 集合推导式
集合推导式用于创建集合,会自动去除重复元素。
基本语法:
python
{expression for item in iterable if condition}
示例:
python
# 从列表中创建不重复的平方数集合
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_squares = {x**2 for x in numbers}
print(unique_squares) # {16, 1, 9, 4}
# 带条件的集合推导式
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0, 64, 4, 36, 16}
2.4 生成器表达式
生成器表达式使用圆括号,与列表推导式类似,但返回一个生成器对象,按需生成值,节省内存。
基本语法:
python
(expression for item in iterable if condition)
示例:
python
# 创建生成器
squares_gen = (x**2 for x in range(10))
# 使用生成器
print(next(squares_gen)) # 0
print(next(squares_gen)) # 1
# 可以转换为列表
print(list(squares_gen)) # [4, 9, 16, 25, 36, 49, 64, 81]
# 在函数中使用
total = sum(x**2 for x in range(10))
print(total) # 285
三、推导式的嵌套和复杂用法
3.1 嵌套推导式
python
# 二维列表展平
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 转置矩阵
transposed = [[row[i] for row in matrix] for i in range(3)]
print(transposed) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
3.2 多重条件推导式
python
# 多个条件
numbers = [x for x in range(20) if x % 2 == 0 if x % 3 == 0]
print(numbers) # [0, 6, 12, 18]
# 复杂的条件表达式
categorized = ["大偶数" if x > 5 and x % 2 == 0 else
"小偶数" if x % 2 == 0 else
"大奇数" if x > 5 else
"小奇数" for x in range(10)]
print(categorized)
四、推导式对比传统循环
4.1 性能比较
推导式通常比等效的循环更快,因为它们在底层使用了优化的C代码。
python
import timeit
# 测试列表推导式性能
list_comp_time = timeit.timeit('[x**2 for x in range(1000)]', number=10000)
loop_time = timeit.timeit('''
result = []
for x in range(1000):
result.append(x**2)
''', number=10000)
print(f"列表推导式: {list_comp_time:.3f}秒")
print(f"传统循环: {loop_time:.3f}秒")
4.2 可读性比较
虽然推导式更简洁,但过度复杂的推导式可能会降低可读性:
python
# 可读性好的推导式
good_example = [x**2 for x in range(10) if x % 2 == 0]
# 过于复杂的推导式(不推荐)
bad_example = [[x*y for y in range(10) if y % 2 == 0] for x in range(10) if x % 3 == 0]
建议:当推导式变得复杂难以理解时,考虑使用传统的循环结构。
五、常见应用场景
5.1 数据清洗和转换
python
# 从字符串中提取数字并转换为整数
data = ["价格: 100元", "重量: 2.5kg", "数量: 15个"]
numbers = [float(''.join(filter(str.isdigit, item))) for item in data]
print(numbers) # [100.0, 25.0, 15.0]
5.2 文件处理
python
# 读取文件并处理行
with open('data.txt', 'r') as file:
lines = [line.strip().upper() for line in file if line.strip()]
5.3 API数据处理
python
# 从API响应中提取特定信息
api_response = [
{'name': 'Alice', 'age': 25, 'active': True},
{'name': 'Bob', 'age': 30, 'active': False},
{'name': 'Charlie', 'age': 35, 'active': True}
]
active_users = [user['name'] for user in api_response if user['active']]
print(active_users) # ['Alice', 'Charlie']
六、注意事项
-
避免过度复杂:如果推导式变得难以阅读,考虑使用传统循环
-
注意内存使用:大型数据集考虑使用生成器表达式
-
保持可读性:适当的空格和换行可以提高复杂推导式的可读性
-
不要滥用:推导式不是所有循环的替代品,选择合适的工具
python
# 可读性更好的复杂推导式
result = [
(x, y, z)
for x in range(10)
for y in range(10)
for z in range(10)
if x + y + z > 15
and x % 2 == 0
and y % 2 != 0
]
print(result)