程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Python 基础

    • 环境搭建
    • 标识符
    • 变量
    • 缩进和注释
    • 数据类型
    • 数据类型转换
    • 运算符
    • 字符串
    • 列表
    • 元组
    • 字典
    • 集合
    • if判断
    • for循环
    • while循环
    • 循环综合练习
    • Python函数
    • 函数与循环实战
    • 生成式
      • 1. 为什么需要生成式?
      • 2. 列表生成式 (List Comprehension)
        • 2.1 基本语法
        • 2.2 带 if 条件的列表生成式
        • 2.3 带 if-else 的列表生成式
        • 2.4 嵌套循环的列表生成式
      • 3. 字典生成式 (Dictionary Comprehension)
      • 4. 集合生成式 (Set Comprehension)
      • 5. 生成器表达式 (Generator Expression)
        • 5.1 语法与核心概念
        • 5.2 为什么使用生成器表达式?—— 节省内存
        • 5.3 使用生成器
      • 6. 总结:何时使用生成式?
    • 文件读写
    • 面向对象
    • 面向对象综合案例
  • Python 进阶

  • Python
  • Python 基础
scholar
2025-07-20
目录

生成式

# Python 生成式

在 Python 中,生成式 (Comprehensions) 是一种极其强大且富有表现力的语法糖。它允许你用一种非常简洁、可读性高的方式,基于一个已有的可迭代对象(如列表、元组等)来创建新的数据结构(如列表、字典、集合)。


# 1. 为什么需要生成式?

在学习生成式之前,让我们先看一个常见的任务:创建一个包含 1 到 10 的平方数的列表。

传统 for 循环写法:

squares = [] # 1. 初始化一个空列表
for x in range(1, 11): # 2. 遍历数字
    squares.append(x ** 2) # 3. 将计算结果追加到列表中

print(squares)
# 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
1
2
3
4
5
6

这个过程需要三行代码。现在,让我们看看列表生成式的写法。

列表生成式写法:

squares = [x ** 2 for x in range(1, 11)]

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

一行代码就完成了同样的工作!这就是生成式的魅力:让代码更紧凑、更优雅、意图更清晰。


# 2. 列表生成式 (List Comprehension)

列表生成式用于快速创建一个新的列表。

# 2.1 基本语法

它的语法结构可以分解为几个部分:

new_list = [output_expression for item in iterable]

  • []: 方括号表示我们正在创建一个列表。
  • output_expression: 输出表达式。对 item 进行处理后的结果,它将成为新列表的元素。
  • for item in iterable: 一个标准的 for 循环,用于遍历源可迭代对象。

# 2.2 带 if 条件的列表生成式

我们还可以在生成式中加入 if 语句,用于筛选元素。

语法模板: new_list = [output_expression for item in iterable if condition]

  • if condition: 一个筛选条件。只有当 condition 为 True 时,output_expression 的结果才会被加入到新列表中。

示例:筛选出10以内的所有偶数并平方

  • 传统 for 循环:

    even_squares = []
    for x in range(1, 11):
        if x % 2 == 0:
            even_squares.append(x ** 2)
    print(even_squares)
    
    1
    2
    3
    4
    5
  • 列表生成式:

    even_squares = [x ** 2 for x in range(1, 11) if x % 2 == 0]
    print(even_squares)
    
    1
    2
  • 输出结果 (两者相同):

    [4, 16, 36, 64, 100]
    
    1

# 2.3 带 if-else 的列表生成式

如果需要根据条件对输出表达式进行选择(类似于三元运算符),if-else 必须放在 for 循环的前面。

语法模板: new_list = [output_if_true if condition else output_if_false for item in iterable]

示例:为数字打上“奇数”或“偶数”的标签

labels = ["偶数" if i % 2 == 0 else "奇数" for i in range(1, 6)]
print(labels)
# 输出: ['奇数', '偶数', '奇数', '偶数', '奇数']
1
2
3

# 2.4 嵌套循环的列表生成式

列表生成式也支持嵌套 for 循环。

示例:生成一个简单的坐标对

  • 传统 for 循环:
    pairs = []
    for x in range(1, 3):
        for y in range(3, 5):
            pairs.append((x, y))
    print(pairs)
    
    1
    2
    3
    4
    5
  • 列表生成式:
    pairs = [(x, y) for x in range(1, 3) for y in range(3, 5)]
    print(pairs)
    
    1
    2
  • 输出结果 (两者相同):
    [(1, 3), (1, 4), (2, 3), (2, 4)]
    
    1
    (注意 for 循环的嵌套顺序与生成式中的顺序是一致的)

# 3. 字典生成式 (Dictionary Comprehension)

与列表生成式类似,字典生成式用于快速创建字典。

语法

new_dict = {key_expression: value_expression for item in iterable if condition}

  • {}: 花括号表示我们正在创建一个字典。
  • key_expression: value_expression: 定义了新字典的键和值。

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

squares_dict = {x: x ** 2 for x in range(1, 6)}
print(squares_dict)
# 输出: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
1
2
3

示例:合并两个列表为一个字典 zip() 函数可以将两个列表的元素一一配对,非常适合用于字典生成式。

keys = ["name", "age", "city"]
values = ["Alice", 30, "New York"]

profile = {k: v for k, v in zip(keys, values)}
print(profile)
# 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}
1
2
3
4
5
6

# 4. 集合生成式 (Set Comprehension)

集合生成式在语法上与列表生成式非常相似,但使用花括号 {},并且其结果是一个集合,这意味着所有元素都是唯一的。

语法

new_set = {output_expression for item in iterable if condition}

示例:从一个有重复元素的列表中提取所有唯一元素的平方

numbers = [1, 2, 2, 3, 4, 4, 5]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares)
# 输出: {1, 4, 9, 16, 25} (重复的2和4被自动去除了)
1
2
3
4

# 5. 生成器表达式 (Generator Expression)

严格来说,Python 没有“元组生成式”。如果你使用圆括号 (),你创建的不是元组,而是一个生成器表达式。

# 5.1 语法与核心概念

语法模板: generator_object = (output_expression for item in iterable if condition)

  • 核心区别:生成器表达式不会立即计算并创建所有元素,而是返回一个生成器对象 (generator object)。
  • 惰性求值 (Lazy Evaluation):生成器只在被迭代时(例如,在 for 循环中)才逐个计算和“生成”下一个值。

# 5.2 为什么使用生成器表达式?—— 节省内存

当你处理非常大的数据集时,一次性创建包含所有结果的列表可能会消耗大量内存。生成器则完美地解决了这个问题。

示例:计算十亿个数的和

# 使用列表生成式 (会尝试创建含10亿个整数的列表,可能导致内存耗尽)
# list_sum = sum([i for i in range(1_000_000_000)]) # 不要运行!

# 使用生成器表达式 (几乎不占内存)
generator = (i for i in range(1_000_000_000))
# sum() 函数可以高效地处理生成器,逐个获取数字并累加
# gen_sum = sum(generator) # 运行也需要很长时间,但内存友好
print("生成器已创建,但内部的数字尚未计算。")
1
2
3
4
5
6
7
8

# 5.3 使用生成器

你可以通过以下方式使用生成器:

  1. 在 for 循环中迭代。
  2. 将其传递给可以处理可迭代对象的函数(如 sum(), list(), tuple(), set())。

重要提示:一个生成器只能被完整地迭代一次。

gen = (x * 2 for x in range(5))

print("第一次迭代:")
for item in gen:
    print(item, end=" ") # 输出: 0 2 4 6 8 

print("\n第二次迭代:")
for item in gen:
    print(item, end=" ") # 无任何输出,因为生成器已经耗尽

# 如果想得到元组,需要用 tuple() 转换
squares_tuple = tuple(x ** 2 for x in range(1, 6))
print("\n转换后的元组:", squares_tuple)
# 输出: (1, 4, 9, 16, 25)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 6. 总结:何时使用生成式?

  • 优点:

    1. 代码简洁:用一行代码代替多行循环,使代码更紧凑。
    2. 可读性高:对于简单的逻辑,生成式的意图一目了然。
    3. 效率:通常比手动 append 的 for 循环稍快。
    4. 内存友好:生成器表达式在处理大数据时有巨大优势。
  • 缺点/注意事项:

    1. 可读性陷阱:当逻辑变得复杂时(例如,超过两层嵌套循环或复杂的 if 条件),生成式会迅速变得难以阅读。
    2. 调试困难:在复杂的生成式中定位错误比在多行 for 循环中更难。

最佳实践法则:

如果逻辑简单,能用一行清晰地表达,就大胆使用生成式。如果逻辑复杂,需要多层嵌套或复杂的条件分支,那么退回到标准的 for 循环通常是更明智的选择,因为它能提供更好的可读性和可维护性。

编辑此页 (opens new window)
上次更新: 2025/07/23, 06:33:16
函数与循环实战
文件读写

← 函数与循环实战 文件读写→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式