admin 管理员组

文章数量: 1184232

Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来

Python系列文章目录

PyTorch系列文章目录

机器学习系列文章目录

深度学习系列文章目录

Java系列文章目录

JavaScript系列文章目录

Python系列文章目录

01-【Python-Day 1】告别编程恐惧:轻松掌握 Python 安装与第一个程序的 6 个步骤
02-【Python-Day 2】掌握Python基石:变量、内存、标识符及int/float/bool数据类型
03-【Python-Day 3】玩转文本:字符串(String)基础操作详解 (上)
04-【Python-Day 4】玩转文本:Python 字符串常用方法深度解析 (下篇)
05-【Python-Day 5】Python 格式化输出实战:%、format()、f-string 对比与最佳实践
06- 【Python-Day 6】从零精通 Python 运算符(上):算术、赋值与比较运算全解析
07-【Python-Day 7】从零精通 Python 运算符(下):逻辑、成员、身份运算与优先级规则全解析
08-【Python-Day 8】从入门到精通:Python 条件判断 if-elif-else 语句全解析
09-【Python-Day 9】掌握循环利器:for 循环遍历序列与可迭代对象详解
10-【Python-Day 10】Python 循环控制流:while 循环详解与 for 循环对比
11-【Python-Day 11】列表入门:Python 中最灵活的数据容器 (创建、索引、切片)
12-【Python-Day 12】Python列表进阶:玩转添加、删除、排序与列表推导式
13-【Python-Day 13】Python 元组 (Tuple) 详解:从创建、操作到高级应用场景一网打尽
14-【Python-Day 14】玩转Python字典(上篇):从零开始学习创建、访问与操作
15-【Python-Day 15】深入探索 Python 字典 (下):常用方法、遍历、推导式与嵌套实战
16-【Python-Day 16】代码复用基石:详解 Python 函数的定义与调用
17-【Python-Day 17】玩转函数参数(上):轻松掌握位置、关键字和默认值
18-【Python-Day 18】玩转函数参数(下):*args 与 **kwargs 终极指南
19-【Python-Day 19】函数的回响:深入理解 return 语句与返回值
20-【Python-Day 20】揭秘Python变量作用域:LEGB规则与global/nonlocal关键字详解
21-【Python-Day 21】一行搞定!Python lambda 匿名函数的妙用与实战
22-【Python-Day 22】代码的基石:模块(Module)的导入与使用详解
23-【Python-Day 23】Python 模块化编程实战:创建、导入及 sys.path 深度解析
24-【Python-Day 24】告别杂乱代码!一文掌握 Python 包(Package)的创建与使用
25-【Python-Day 25】玩转数字:精通 math 与 random 模块,从数学运算到随机抽样
26-【Python-Day 26】解锁时间魔法:深入解析 time 与 datetime 模块
27-【Python-Day 27】轻松驾驭操作系统:精通 os 与 sys 模块核心功能
28-【Python-Day 28】从指令到蓝图:Python面向对象编程(OOP)入门指南
29-【Python-Day 29】万物皆对象:详解 Python 类的定义、实例化与 __init__ 方法
30-【Python-Day 30】从 self、cls 到 @staticmethod:Python 面向对象三大方法深度解析
31-【Python-Day 31】一文搞懂 Python 实例属性与类属性:从定义、区别到应用场景
32-【Python-Day 32】面向对象基石之封装:从 __private@property 的深度解析
33-【Python-Day 33】OOP核心之继承(Inheritance):代码复用与扩展的艺术
34-【Python-Day 34】深入解析Python继承:super()函数、MRO与菱形继承问题
35-【Python-Day 35】深入理解多态:代码更灵活的“鸭子类型”魔法
36-【Python-Day 36】解密文件IO:一文搞懂 Python 读写模式、编码与指针操作
37-【Python-Day 37】程序的守护者:一文彻底搞懂 Python 异常处理 (try-except-else-finally)
38-【Python-Day 38】告别通用错误!一文学会创建和使用 Python 自定义异常
39-【Python-Day 39】精通Python推导式:告别冗长for循环,提升代码效率与格调


文章目录

  • Langchain系列文章目录
  • Python系列文章目录
  • PyTorch系列文章目录
  • 机器学习系列文章目录
  • 深度学习系列文章目录
  • Java系列文章目录
  • JavaScript系列文章目录
  • Python系列文章目录
  • 摘要
  • 一、推导式:代码的“浓缩咖啡”
  • 二、列表推导式 (List Comprehension)
    • 2.1 基本语法结构
    • 2.2 基础应用示例
      • 2.2.1 不带 `if` 条件的推导式
        • (1) 示例:将列表中的所有字符串转为大写
      • 2.2.2 带 `if` 条件的推导式
        • (1) 示例:提取列表中的所有偶数
  • 三、字典推导式 (Dictionary Comprehension)
    • 3.1 基本语法结构
    • 3.2 应用示例
      • 3.2.1 示例:创建数字及其平方的字典
      • 3.2.2 示例:快速交换字典的键和值
  • 四、集合推导式 (Set Comprehension)
    • 4.1 基本语法结构
    • 4.2 应用示例
      • 4.2.1 示例:从列表中提取所有单词的首字母并去重
  • 五、进阶用法与对比
    • 5.1 嵌套推导式
        • (1) 示例:扁平化一个二维列表(矩阵)
    • 5.2 推导式 vs `map()` 和 `filter()`
      • 5.2.1 对比分析
  • 六、总结


摘要

在 Python 编程中,我们经常需要基于一个已有的序列(如列表、元组等)来创建一个新的序列。传统的方法是使用 for 循环,但 Python 提供了一种更为强大、简洁且高效的语法糖——推导式 (Comprehensions)。本文将带你深入探索 Python 中三种核心的推导式:列表推导式、字典推导式和集合推导式。你将学会如何使用它们来编写更具 Pythonic 风格的代码,理解其内部工作原理,掌握嵌套推导式等高级用法,并明确其与 mapfilter 等函数的区别与优势。

一、推导式:代码的“浓缩咖啡”

在正式学习之前,我们先来看一个场景:创建一个包含 0 到 9 的平方数的列表。

使用传统的 for 循环,代码是这样的:

# 传统 for 循环方法
squares = []
for i in range(10):
    squares.append(i * i)

print(squares)
# 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

代码清晰,但略显冗长。而使用列表推导式,我们可以一行代码搞定:

# 列表推导式方法
squares = [i * i for i in range(10)]

print(squares)
# 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

是不是瞬间感觉代码变得紧凑而优雅了?推导式就像是 Python 代码的“浓缩咖啡”,它将一个循环、一个条件判断(可选)和一个表达式浓缩到一行代码中,不仅减少了代码量,还提高了可读性和执行效率。

二、列表推导式 (List Comprehension)

列表推导式是最常用的一种推导式,用于快速生成新的列表。

2.1 基本语法结构

列表推导式的语法结构可以拆解为几个部分,非常直观。

新列表 = [ 表达式
expression
for 循环
for item in iterable
可选的 if 条件
if condition
]
  • 表达式 (expression): 对迭代出的每个元素进行处理的操作,结果将作为新列表的元素。
  • for 循环 (for item in iterable): 遍历一个可迭代对象(如列表、元组、字符串、range 等)。
  • if 条件 (if condition): 可选部分,用于筛选可迭代对象中的元素。只有满足条件的元素才会被表达式处理。

2.2 基础应用示例

2.2.1 不带 if 条件的推导式

这是最简单的形式,对原序列的每个元素执行操作。

(1) 示例:将列表中的所有字符串转为大写
words = ['hello', 'world', 'python', 'is', 'awesome']

# for 循环实现
upper_words_loop = []
for word in words:
    upper_words_loop.append(word.upper())
print(f"For 循环结果: {upper_words_loop}")

# 列表推导式实现
upper_words_comprehension = [word.upper() for word in words]
print(f"推导式结果:   {upper_words_comprehension}")

输出:

For 循环结果: ['HELLO', 'WORLD', 'PYTHON', 'IS', 'AWESOME']
推导式结果:   ['HELLO', 'WORLD', 'PYTHON', 'IS', 'AWESOME']

2.2.2 带 if 条件的推导式

通过添加 if 子句,我们可以轻松地在迭代过程中进行筛选。

(1) 示例:提取列表中的所有偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# for 循环实现
even_numbers_loop = []
for num in numbers:
    if num % 2 == 0:
        even_numbers_loop.append(num)
print(f"For 循环结果: {even_numbers_loop}")

# 列表推导式实现
even_numbers_comprehension = [num for num in numbers if num % 2 == 0]
print(f"推导式结果:   {even_numbers_comprehension}")

输出:

For 循环结果: [2, 4, 6, 8, 10]
推导式结果:   [2, 4, 6, 8, 10]

三、字典推导式 (Dictionary Comprehension)

与列表推导式类似,字典推导式可以让我们用一行代码优雅地创建字典。

3.1 基本语法结构

字典推导式的语法与列表推导式非常相似,只是用了花括号 {},并且表达式部分是 key: value 键值对的形式。

{key_expression: value_expression for item in iterable if condition}

3.2 应用示例

3.2.1 示例:创建数字及其平方的字典

# for 循环实现
square_dict_loop = {}
for i in range(5):
    square_dict_loop[i] = i * i
print(f"For 循环结果: {square_dict_loop}")

# 字典推导式实现
square_dict_comprehension = {i: i * i for i in range(5)}
print(f"推导式结果:   {square_dict_comprehension}")

输出:

For 循环结果: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
推导式结果:   {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

3.2.2 示例:快速交换字典的键和值

假设我们有一个字典,其值都是唯一的,我们想创建一个新字典,将原字典的键和值互换。

# 原始字典
original_dict = {'a': 1, 'b': 2, 'c': 3}

# 字典推导式实现
swapped_dict = {value: key for key, value in original_dict.items()}
print(f"交换后的字典: {swapped_dict}")

输出:

交换后的字典: {1: 'a', 2: 'b', 3: 'c'}

这里我们遍历了 original_dict.items(),它会产生 (key, value) 形式的元组,然后我们用 value 作为新键,key 作为新值。

四、集合推导式 (Set Comprehension)

集合推导式用于创建集合,它的语法也使用花括号 {},但与字典不同的是,它只包含一个表达式,而不是键值对。

4.1 基本语法结构

{expression for item in iterable if condition}

由于集合的特性(元素不重复),集合推导式天然具有去重的功能。

4.2 应用示例

4.2.1 示例:从列表中提取所有单词的首字母并去重

words = ['apple', 'banana', 'apple', 'cherry', 'blueberry', 'banana']

# for 循环实现
first_letters_loop = set()
for word in words:
    first_letters_loop.add(word[0])
print(f"For 循环结果: {first_letters_loop}")

# 集合推导式实现
first_letters_comprehension = {word[0] for word in words}
print(f"推导式结果:   {first_letters_comprehension}")

输出:

For 循环结果: {'c', 'b', 'a'}
推导式结果:   {'c', 'b', 'a'}

注意输出结果是无序的,这是集合的特性。

五、进阶用法与对比

5.1 嵌套推导式

推导式可以嵌套,就像 for 循环可以嵌套一样。这在处理多维数据结构(如矩阵)时非常有用。

(1) 示例:扁平化一个二维列表(矩阵)

假设我们有一个矩阵,想把它转换成一个一维列表。

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# for 循环实现
flattened_loop = []
for row in matrix:
    for item in row:
        flattened_loop.append(item)
print(f"For 循环结果: {flattened_loop}")

# 嵌套列表推导式实现
flattened_comprehension = [item for row in matrix for item in row]
print(f"推导式结果:   {flattened_comprehension}")

输出:

For 循环结果: [1, 2, 3, 4, 5, 6, 7, 8, 9]
推导式结果:   [1, 2, 3, 4, 5, 6, 7, 8, 9]

阅读技巧:阅读嵌套推导式时,从左到右依次看 for 循环部分,这与传统 for 循环的嵌套顺序是一致的。

⚠️ 注意:虽然嵌套推导式很强大,但过度嵌套(超过两层)会严重降低代码的可读性。在这种情况下,回归使用传统的 for 循环可能是更好的选择。

5.2 推导式 vs map()filter()

在推导式出现之前,Python 程序员通常使用内置的 map()filter() 函数来完成类似的任务。

  • filter(function, iterable): 过滤序列,返回一个迭代器,只包含 function(item)True 的元素。
  • map(function, iterable): 将函数应用于序列的每个元素,返回一个包含结果的迭代器。

让我们用 mapfilter 重写“提取偶数并求平方”的例子。

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# map 和 filter 组合实现
# 1. 定义一个检查偶数的函数
def is_even(n):
    return n % 2 == 0

# 2. 定义一个求平方的函数
def square(n):
    return n * n

# 3. 先 filter 再 map
result_map_filter = list(map(square, filter(is_even, numbers)))
print(f"map/filter 结果: {result_map_filter}")

# 使用 lambda 表达式简化
result_lambda = list(map(lambda n: n*n, filter(lambda n: n%2==0, numbers)))
print(f"lambda 结果:    {result_lambda}")


# 列表推导式实现
result_comprehension = [n * n for n in numbers if n % 2 == 0]
print(f"推导式结果:      {result_comprehension}")

输出:

map/filter 结果: [4, 16, 36, 64, 100]
lambda 结果:    [4, 16, 36, 64, 100]
推导式结果:      [4, 16, 36, 64, 100]

5.2.1 对比分析

特性推导式map / filter
可读性通常更高,将逻辑整合在一处,更接近自然语言。需要定义额外函数或使用 lambda,逻辑分散。
灵活性非常灵活,可以在一个表达式中完成复杂的转换和筛选。功能单一,map 负责转换,filter 负责筛选,通常需要组合使用。
性能通常比 map/filter 组合更快,因为 Python 解释器对其有优化。函数调用有开销,速度可能稍慢。
适用场景适用于从一个序列创建另一个序列的绝大多数场景。当有一个已经存在的复杂函数需要应用到序列时,map 仍然是不错的选择。

总的来说,当逻辑相对简单时,推导式是更 Pythonic、更推荐的选择。

六、总结

推导式是 Python 语言中一个极具特色的功能,它提供了一种创建列表、字典和集合的优雅而高效的方式。掌握推导式是迈向 Python 高手的重要一步。

  1. 核心思想:将循环、条件判断和表达式浓缩在一行代码中,以简洁的方式从一个可迭代对象生成新的序列。
  2. 三种类型
    • 列表推导式 [...]:最常用,用于生成列表。
    • 字典推导式 {k: v ...}:用于生成字典,表达式为键值对。
    • 集合推导式 {...}:用于生成集合,表达式为单个值,并自动去重。
  3. 语法结构[expr for item in iterable if condition] 是基本骨架,理解这三个部分是关键。
  4. 高级应用:嵌套推导式可以处理多维数据,但要注意保持代码的可读性,避免过度嵌套。
  5. 优势:相比传统的 for 循环,推导式代码更简洁;相比 map/filter,可读性和性能通常更优。拥抱推导式,让你的 Python 代码更加地道、高效!

本文标签: 冗长 格调 效率 代码 python