深入理解 Python 中的推导式(Comprehension):简洁高效的序列创建方式

68 阅读4分钟

引言: 推导式是 Python 中极具 “Pythonic” 风格的语法糖,它能以一行代码简洁、高效地创建列表、字典、集合甚至生成器,大幅简化常规的循环 + 判断逻辑。本文聚焦推导式这一核心知识点,从基础语法、分类用法到进阶技巧,帮你彻底掌握这一提升代码简洁度的实用技能。

一、推导式的核心概念

推导式(Comprehension)本质是将 “循环遍历 - 条件判断 - 元素处理” 的多行逻辑浓缩为一行的语法结构,核心优势是:

  • 代码更简洁,符合 Python “简洁胜于复杂” 的设计哲学;
  • 执行效率更高(底层由 C 语言实现,比纯 Python 循环更快);
  • 逻辑更集中,便于阅读和维护。

推导式主要分为三类:列表推导式、字典推导式、集合推导式,此外还有生成器推导式(也叫生成器表达式),是推导式与生成器的结合。

二、列表推导式(List Comprehension)

1. 基础语法

# 基本格式:[表达式 for 元素 in 可迭代对象 if 条件]
# 对比:传统循环 vs 列表推导式

# 传统循环:创建1-10的偶数列表
even_nums = []
for num in range(1, 11):
    if num % 2 == 0:
        even_nums.append(num)
print(even_nums)  # 输出:[2, 4, 6, 8, 10]

# 列表推导式:一行实现
even_nums = [num for num in range(1, 11) if num % 2 == 0]
print(even_nums)  # 输出:[2, 4, 6, 8, 10]

2. 进阶用法:嵌套推导式

适用于处理嵌套的可迭代对象(比如二维列表):

# 需求:将二维列表扁平化([[1,2], [3,4], [5,6]] → [1,2,3,4,5,6])
nested_list = [[1,2], [3,4], [5,6]]

# 传统循环
flat_list = []
for sub_list in nested_list:
    for num in sub_list:
        flat_list.append(num)

# 嵌套列表推导式
flat_list = [num for sub_list in nested_list for num in sub_list]
print(flat_list)  # 输出:[1,2,3,4,5,6]

三、字典推导式(Dictionary Comprehension)

1. 基础语法

# 基本格式:{键表达式: 值表达式 for 元素 in 可迭代对象 if 条件}

# 需求:创建数字1-5为键、平方为值的字典
# 传统循环
square_dict = {}
for num in range(1, 6):
    square_dict[num] = num **2
print(square_dict)  # 输出:{1:1, 2:4, 3:9, 4:16, 5:25}

# 字典推导式
square_dict = {num: num** 2 for num in range(1, 6)}
print(square_dict)  # 输出同上

# 带条件:只保留偶数的平方
even_square_dict = {num: num**2 for num in range(1, 6) if num % 2 == 0}
print(even_square_dict)  # 输出:{2:4, 4:16}

2. 实用场景:字典键值互换

original_dict = {"a": 1, "b": 2, "c": 3}
reverse_dict = {v: k for k, v in original_dict.items()}
print(reverse_dict)  # 输出:{1:'a', 2:'b', 3:'c'}

四、集合推导式(Set Comprehension)

集合推导式语法与列表推导式类似,区别是用{}包裹,且会自动去重(集合的特性):

# 基本格式:{表达式 for 元素 in 可迭代对象 if 条件}

# 需求:提取列表中大于5的唯一数字
num_list = [3, 7, 5, 8, 7, 9, 5, 10]
unique_nums = {num for num in num_list if num > 5}
print(unique_nums)  # 输出:{7, 8, 9, 10}(无序,且去重)

五、生成器推导式(Generator Expression)

语法上把列表推导式的[]换成(),它不会一次性生成所有元素,而是返回一个生成器对象,占用极少内存:

# 列表推导式:一次性生成所有元素,占用内存
list_comp = [num for num in range(1000000)]
print(type(list_comp))  # <class 'list'>
print(sys.getsizeof(list_comp))  # 约8MB(视环境而定)

# 生成器推导式:仅创建生成器对象,内存占用可忽略
gen_comp = (num for num in range(1000000))
print(type(gen_comp))  # <class 'generator'>
print(sys.getsizeof(gen_comp))  # 约100字节(固定大小)

# 遍历生成器推导式
for num in gen_comp:
    if num > 10:
        break
    print(num)  # 输出0-10

六、推导式的使用原则

  1. 简洁优先:如果推导式超过 2 行逻辑(比如多层嵌套、复杂条件),建议改用普通循环,避免可读性下降;
  2. 避免过度使用:不要为了 “炫技” 而强行用推导式,代码的可维护性比简洁更重要;
  3. 内存考量:处理超大数据集时,优先用生成器推导式而非列表推导式。

总结

  1. 推导式是 Python 特有的简洁语法,核心是将 “循环 + 判断” 逻辑浓缩为一行,分为列表、字典、集合、生成器推导式四类;
  2. 列表推导式用[],字典推导式用{k:v},集合推导式用{},生成器推导式用()
  3. 推导式执行效率高于普通 Python 循环,但需注意可读性,复杂逻辑建议改用常规循环