Python推导式完全指南
专为编程小白设计 • 用通俗语言解释复杂概念 • 附大量实用示例
什么是推导式?
推导式是Python中一种简洁高效的创建数据结构的方法,可以让你用一行代码生成列表、字典、集合等。
简单来说,推导式就是创建新数据结构的”快捷方式”,把多行代码压缩成一行。
推导式 = 循环 + 条件判断 + 创建新结构
💡 为什么用推导式?
1. 代码更简洁:一行替代多行
2. 执行效率更高:比普通循环快
3. 可读性更好(熟练后)
4. Python风格:更”Pythonic”的写法
传统方法 vs 推导式对比
传统方法(4行)
numbers = []
for i in range(10):
if i % 2 == 0:
numbers.append(i*2)
for i in range(10):
if i % 2 == 0:
numbers.append(i*2)
推导式(1行)
numbers = [i*2 for i in range(10) if i % 2 == 0]
列表推导式 (最常用)
基本结构:[表达式 for 变量 in 可迭代对象 if 条件]
相当于把循环和条件判断压缩到一行,返回一个新的列表
基础示例
# 生成0-9的平方
squares = [x**2 for x in range(10)]
print(squares)
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)
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)
[0, 4, 16, 36, 64]
多重循环
# 生成所有坐标组合
points = [(x, y) for x in range(3) for y in range(3)]
print(points)
points = [(x, y) for x in range(3) for y in range(3)]
print(points)
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
📝 小贴士
列表推导式中可以包含多个if条件,甚至使用三元表达式:
# 将列表中的负数转为0
numbers = [5, -2, 10, -8, 3]
processed = [x if x >= 0 else 0 for x in numbers]
numbers = [5, -2, 10, -8, 3]
processed = [x if x >= 0 else 0 for x in numbers]
字典推导式
基本结构:{键:值 for 变量 in 可迭代对象 if 条件}
用于快速生成字典,非常适用于键值转换和数据转换
基础示例
# 创建数字到平方的映射
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
键值交换
# 键值互换
student_grades = {“Alice”: 90, “Bob”: 85, “Charlie”: 92}
swapped = {v: k for k, v in student_grades.items()}
print(swapped)
student_grades = {“Alice”: 90, “Bob”: 85, “Charlie”: 92}
swapped = {v: k for k, v in student_grades.items()}
print(swapped)
{90: ‘Alice’, 85: ‘Bob’, 92: ‘Charlie’}
条件过滤
# 只保留成绩大于90的学生
top_students = {k: v for k, v in student_grades.items() if v > 90}
print(top_students)
top_students = {k: v for k, v in student_grades.items() if v > 90}
print(top_students)
{‘Charlie’: 92}
⚠️ 注意
当值重复时进行键值交换会丢失数据(字典键必须唯一)
集合推导式
基本结构:{表达式 for 变量 in 可迭代对象 if 条件}
与列表推导式类似,但使用花括号{},且自动去除重复元素
基础示例
# 生成字符串长度的集合
words = [“apple”, “banana”, “cherry”, “date”]
lengths = {len(word) for word in words}
print(lengths)
words = [“apple”, “banana”, “cherry”, “date”]
lengths = {len(word) for word in words}
print(lengths)
{5, 6} # 注意:自动去重
列表去重
# 快速去除列表重复项
numbers = [1, 2, 2, 3, 4, 4, 4, 5]
unique = {x for x in numbers}
print(unique)
numbers = [1, 2, 2, 3, 4, 4, 4, 5]
unique = {x for x in numbers}
print(unique)
{1, 2, 3, 4, 5}
📝 集合特性
集合是无序的且不包含重复元素,非常适合用来去重和检查成员存在性
生成器表达式
基本结构:(表达式 for 变量 in 可迭代对象 if 条件)
使用圆括号(),返回生成器对象而不是实际数据,节省内存
基础示例
# 创建生成器
gen = (x**2 for x in range(1000000))
print(gen)
print(next(gen)) # 获取第一个值
print(next(gen)) # 获取第二个值
gen = (x**2 for x in range(1000000))
print(gen)
print(next(gen)) # 获取第一个值
print(next(gen)) # 获取第二个值
<generator object <genexpr> at 0x…>
0
1
0
1
内存对比
import sys
# 列表推导式
list_comp = [x**2 for x in range(1000000)]
print(sys.getsizeof(list_comp)) # 占用内存较大
# 生成器表达式
gen_exp = (x**2 for x in range(1000000))
print(sys.getsizeof(gen_exp)) # 占用内存极小
# 列表推导式
list_comp = [x**2 for x in range(1000000)]
print(sys.getsizeof(list_comp)) # 占用内存较大
# 生成器表达式
gen_exp = (x**2 for x in range(1000000))
print(sys.getsizeof(gen_exp)) # 占用内存极小
8697464 # 约8.3MB
112 # 仅112字节
112 # 仅112字节
⏱️ 何时使用生成器
1. 处理大量数据(内存不足时)
2. 只需访问一次数据
3. 数据流处理(如读取大文件)
最佳实践与注意事项
推导式虽好,但也要用得恰当,否则可能降低代码可读性
✅ 推荐做法
1. 保持简短:复杂的逻辑还是用传统循环
2. 优先可读性:不要为了简洁而牺牲可读性
3. 命名有意义:变量名要能表达含义
4. 使用生成器处理大数据
❌ 避免这些情况
1. 过度嵌套:多重循环+复杂条件会很难读
2. 副作用操作:避免在推导式中修改外部状态
3. 太长的一行:超过80字符应考虑拆分
4. 重复计算:不要在表达式中重复计算相同值
反例:过度复杂
# 难以理解的推导式
result = [x*y for x in range(10) if x%2==0 for y in range(5) if y>2]
# 更好的写法(使用传统循环)
result = []
for x in range(10):
if x % 2 == 0:
for y in range(5):
if y > 2:
result.append(x*y)
result = [x*y for x in range(10) if x%2==0 for y in range(5) if y>2]
# 更好的写法(使用传统循环)
result = []
for x in range(10):
if x % 2 == 0:
for y in range(5):
if y > 2:
result.append(x*y)