【Python】Python之什么是生成器?什么是迭代器?

目录

  • 专栏导读
    • 前言
    • 什么是迭代器(Iterator)?
      • 迭代器的定义
      • 迭代器协议
      • 可迭代对象 vs 迭代器
      • 自定义迭代器
      • 迭代器的优势
    • 什么是生成器(Generator)?
      • 生成器的定义
      • 生成器函数
      • 生成器表达式
      • 复杂的生成器示例
      • 生成器的状态保持
    • 迭代器 vs 生成器对比
    • 实际应用场景
      • 1. 读取大文件
      • 2. 数据流处理
      • 3. 无限序列
    • 高级特性
      • 1. 生成器的方法
      • 2. 异常处理
    • 性能比较
    • 最佳实践
      • 1. 何时使用迭代器
      • 2. 何时使用生成器
      • 3. 注意事项
    • 总结
  • 结尾

专栏导读

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手

  • 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注

  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏求订阅

  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏求订阅

  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏求订阅

  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏

  • ❤️ 欢迎各位佬关注! ❤️

前言

在Python编程中,迭代器(Iterator)和生成器(Generator)是两个非常重要且强大的概念。它们不仅能让我们的代码更加优雅和高效,还能帮助我们处理大量数据时节省内存。本文将深入探讨这两个概念,并通过丰富的示例来帮助大家理解和掌握它们。

什么是迭代器(Iterator)?

迭代器的定义

迭代器是一个可以记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器协议

在Python中,迭代器需要实现两个方法:

  • __iter__():返回迭代器对象本身
  • __next__():返回下一个值,如果没有更多元素则抛出StopIteration异常

可迭代对象 vs 迭代器

# 可迭代对象(Iterable)
my_list = [1, 2, 3, 4, 5]
my_string = "hello"
my_dict = {'a': 1, 'b': 2}# 检查是否为可迭代对象
from collections.abc import Iterable
print(isinstance(my_list, Iterable))  # True
print(isinstance(my_string, Iterable))  # True
print(isinstance(my_dict, Iterable))  # True# 获取迭代器
list_iterator = iter(my_list)
print(type(list_iterator))  # <class 'list_iterator'># 使用迭代器
print(next(list_iterator))  # 1
print(next(list_iterator))  # 2
print(next(list_iterator))  # 3

自定义迭代器

class NumberIterator:def __init__(self, start, end):self.start = startself.end = endself.current = startdef __iter__(self):return selfdef __next__(self):if self.current < self.end:result = self.currentself.current += 1return resultelse:raise StopIteration# 使用自定义迭代器
numbers = NumberIterator(1, 5)
for num in numbers:print(num)  # 输出: 1, 2, 3, 4

迭代器的优势

1. **内存效率**:迭代器是惰性求值的,只在需要时才计算下一个值
2. **节省空间**:不需要将所有元素同时存储在内存中
3. **适合处理大数据集**:可以处理无限序列或非常大的数据集

什么是生成器(Generator)?

生成器的定义

生成器是一种特殊的迭代器,它使用`yield`关键字来产生值。生成器函数在调用时不会立即执行,而是返回一个生成器对象。

生成器函数

def simple_generator():yield 1yield 2yield 3# 创建生成器对象
gen = simple_generator()
print(type(gen))  # <class 'generator'># 使用生成器
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# print(next(gen))  # 会抛出 StopIteration 异常

生成器表达式

# 列表推导式
squares_list = [x**2 for x in range(10)]
print(type(squares_list))  # <class 'list'># 生成器表达式
squares_gen = (x**2 for x in range(10))
print(type(squares_gen))  # <class 'generator'># 比较内存使用
import sys
print(f"列表大小: {sys.getsizeof(squares_list)} bytes")
print(f"生成器大小: {sys.getsizeof(squares_gen)} bytes")

复杂的生成器示例

def fibonacci_generator(n):"""生成斐波那契数列的前n项"""a, b = 0, 1count = 0while count < n:yield aa, b = b, a + bcount += 1# 使用斐波那契生成器
fib_gen = fibonacci_generator(10)
for num in fib_gen:print(num, end=" ")  # 输出: 0 1 1 2 3 5 8 13 21 34
print()

生成器的状态保持

def counter_generator():count = 0while True:value = yield countif value is not None:count = valueelse:count += 1# 使用带状态的生成器
counter = counter_generator()
print(next(counter))  # 0
print(next(counter))  # 1
print(counter.send(10))  # 10
print(next(counter))  # 11

迭代器 vs 生成器对比

特性迭代器生成器
定义方式实现__iter____next__方法使用yield关键字或生成器表达式
代码复杂度相对复杂简洁优雅
内存使用惰性求值惰性求值
状态管理手动管理自动管理
是否为迭代器是(特殊的迭代器)

实际应用场景

1. 读取大文件

def read_large_file(file_path):"""逐行读取大文件,节省内存"""with open(file_path, 'r', encoding='utf-8') as file:for line in file:yield line.strip()# 使用示例
# for line in read_large_file('large_file.txt'):
#     process_line(line)

2. 数据流处理

def data_processor(data_source):"""处理数据流"""for item in data_source:# 进行数据清洗和转换processed_item = item.upper().strip()if processed_item:  # 过滤空值yield processed_item# 链式处理
raw_data = ['  hello  ', '  world  ', '', '  python  ']
processed_data = data_processor(raw_data)
for item in processed_data:print(f"处理后: {item}")

3. 无限序列

def infinite_sequence():"""生成无限序列"""num = 0while True:yield numnum += 1# 使用无限序列(注意要有退出条件)
inf_gen = infinite_sequence()
for i, num in enumerate(inf_gen):if i >= 10:  # 只取前10个breakprint(num, end=" ")  # 输出: 0 1 2 3 4 5 6 7 8 9
print()

高级特性

1. 生成器的方法

def advanced_generator():try:value = yield "开始"while True:if value == "stop":return "生成器结束"value = yield f"接收到: {value}"except GeneratorExit:print("生成器被关闭")finally:print("清理资源")# 使用生成器方法
gen = advanced_generator()
print(next(gen))  # 开始
print(gen.send("hello"))  # 接收到: hello
print(gen.send("world"))  # 接收到: world
try:print(gen.send("stop"))  # 抛出 StopIteration,值为 "生成器结束"
except StopIteration as e:print(f"返回值: {e.value}")

2. 异常处理

def error_handling_generator():try:yield 1yield 2yield 3except ValueError as e:yield f"捕获到错误: {e}"yield "继续执行"gen = error_handling_generator()
print(next(gen))  # 1
print(gen.throw(ValueError, "测试错误"))  # 捕获到错误: 测试错误
print(next(gen))  # 继续执行

性能比较

import time
import sysdef performance_comparison():# 列表方式start_time = time.time()squares_list = [x**2 for x in range(1000000)]list_time = time.time() - start_timelist_memory = sys.getsizeof(squares_list)# 生成器方式start_time = time.time()squares_gen = (x**2 for x in range(1000000))gen_time = time.time() - start_timegen_memory = sys.getsizeof(squares_gen)print(f"列表创建时间: {list_time:.6f}秒")print(f"生成器创建时间: {gen_time:.6f}秒")print(f"列表内存使用: {list_memory:,} bytes")print(f"生成器内存使用: {gen_memory:,} bytes")print(f"内存节省比例: {(list_memory - gen_memory) / list_memory * 100:.2f}%")performance_comparison()

最佳实践

1. 何时使用迭代器

  • 需要自定义复杂的迭代逻辑
  • 需要实现特殊的迭代行为
  • 构建可重用的迭代器类

2. 何时使用生成器

  • 处理大量数据时节省内存
  • 创建数据流水线
  • 实现惰性求值
  • 生成无限序列

3. 注意事项

# 生成器只能迭代一次
gen = (x for x in range(3))
print(list(gen))  # [0, 1, 2]
print(list(gen))  # [] 空列表,生成器已耗尽# 如果需要多次迭代,重新创建生成器
def create_generator():return (x for x in range(3))gen1 = create_generator()
gen2 = create_generator()
print(list(gen1))  # [0, 1, 2]
print(list(gen2))  # [0, 1, 2]

总结

迭代器和生成器是Python中强大的工具,它们提供了优雅且内存高效的方式来处理数据序列。主要要点包括:

  • 1. **迭代器**是实现了迭代器协议的对象,可以逐个访问元素
  • 2. **生成器**是特殊的迭代器,使用`yield`关键字,代码更简洁
  • 3. 两者都支持**惰性求值**,节省内存空间
  • 4. 适用于处理**大数据集**和**无限序列**
  • 5. 生成器提供了`send()`、`throw()`、`close()`等高级方法

掌握迭代器和生成器的使用,将让你的Python代码更加高效和优雅。在处理大量数据或需要节省内存的场景中,它们是不可或缺的工具。


结尾

  • 希望对初学者有帮助;致力于办公自动化的小小程序员一枚

  • 希望能得到大家的【❤️一个免费关注❤️】感谢!

  • 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍

  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏

  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏

  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84824.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python中实现简单爬虫并处理数据

在当今数据驱动的时代&#xff0c;能够从互联网上高效地抓取信息变得越来越重要。Python因其简洁易学的特性&#xff0c;成为了编写网络爬虫的首选语言之一。接下来&#xff0c;我将介绍如何使用Python来实现一个基础的网络爬虫&#xff0c;并对收集到的数据进行初步处理。 首先…

免费wordpress主题网

免费WordPress主题网 WP模板牛 WP模板牛是一个提供免费WordPress主题的网站&#xff0c;用户可以在这里找到大量高质量的模板&#xff0c;适用于各种网站类型。该网站致力于为用户提供简单、高效的建站体验。 官网链接&#xff1a; https://wpniu.com 建站哥模板 建站哥模板…

为什么需要MyBatis-Plus条件构造器?

目录 前言 一、传统SQL编写的痛点 二、条件构造器的核心优势 1. 防SQL注入&#xff08;安全性&#xff09; 2. 面向对象编程&#xff08;可读性&#xff09; 3. 动态条件构建&#xff08;灵活性&#xff09; 4. 数据库无关性&#xff08;可移植性&#xff09; 三、典型应…

【从零学习JVM|第九篇】常见的垃圾回收算法和垃圾回收器

前言&#xff1a; 我们知道在堆内存中&#xff0c;会有自动的垃圾回收功能&#xff0c;那今天这篇文章将会向你介绍&#xff0c;这个功能实现的方式&#xff0c;还有实现的对象&#xff0c;接下来就由我来给你们详细介绍垃圾回收的算法和实现算法的回收器。 目录 前言&#…

品牌窜货治理解决方案

在渠道网络的暗潮中&#xff0c;窜货犹如隐秘的漩涡&#xff0c;某知名白酒品牌曾因区域窜货导致终端价格体系崩溃&#xff0c;半年内损失超3亿元。窜货行为不仅破坏市场秩序&#xff0c;更会引发信任危机。随着电商平台的多元化与分销层级的复杂化&#xff0c;品牌方亟需构建一…

车载电子电器架构 --- 法律和标准对电子电气架构的影响

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

一种通用跨平台实现SEH的解决方案

一. 前言 众所周知&#xff0c;在软件的代码中&#xff0c;处理软件本身的逻辑只要大约1/3的代码&#xff0c;另外2/3的代码实际上是在处理各种各样的异常情况。 这些异常情况一方面是因为不同用户之间不同的硬件软件环境要处理。另一方面是程序中可能出现的bug。比较典型的情…

25.6.19学习总结

什么是堆&#xff08;Heap&#xff09;&#xff1f; 堆是一种特殊的树形数据结构&#xff0c;它满足以下两个主要属性&#xff1a; 结构性&#xff08;完全二叉树&#xff09;&#xff1a; 堆总是一个完全二叉树 (Complete Binary Tree)。这意味着&#xff0c;除了最后一层&am…

【前后前】导入Excel文件闭环模型:Vue3前端上传Excel文件,【Java后端接收、解析、返回数据】,Vue3前端接收展示数据

【前后前】导入Excel文件闭环模型&#xff1a;Vue3前端上传Excel文件&#xff0c;【Java后端接收、解析、返回数据】&#xff0c;Vue3前端接收展示数据 一、Vue3前端上传&#xff08;导入&#xff09;Excel文件 ReagentInDialog.vue <script setup lang"ts" na…

网络基础入门:从OSI模型到TCP/IP协议详解

网络基础入门&#xff1a;从OSI模型到TCP/IP协议详解 一、网络基础概念与OSI七层模型 1.1 网络通信的本质 计算机网络的核心是将抽象语言转换为二进制数据进行传输与计算&#xff0c;这一过程涉及多层抽象与转换&#xff1a; 应用层&#xff1a;人机交互—抽象语言------编…

Linux致命漏洞CVE-2025-6018和CVE-2025-6019

Qualys 最近披露了两个影响主流 Linux 发行版的本地权限提升 (LPE) 漏洞&#xff0c;分别是 CVE-2025-6018 和 CVE-2025-6019。这两个漏洞可以被串联利用&#xff0c;使得非特权用户在几秒钟内获得系统的 root 权限&#xff0c;从而实现对系统的完全控制。 一、漏洞详情 这两…

【Docker基础】Docker镜像管理:docker push详解

目录 引言 1 Docker镜像推送基础概念 1.1 什么是Docker镜像推送 1.2 镜像仓库概述 1.3 镜像标签与版本控制 2 docker push命令详解 2.1 基本语法 2.2 常用参数选项 2.3 实际命令示例 2.4 推送流程 2.5 步骤描述 3 镜像推送实践示例 3.1 登录管理 3.2 标签管理 3…

FPGA基础 -- Verilog行为建模之循环语句

行为级建模&#xff08;Behavioral Modeling&#xff09;是 Verilog HDL 中最接近软件编程语言的一种描述方式&#xff0c;适用于功能建模和仿真建模的初期阶段。在行为级中&#xff0c;循环语句&#xff08;loop statements&#xff09;是常见且重要的控制结构&#xff0c;用于…

从C学C++(7)——static成员

从C学C(7)——static成员 若无特殊说明&#xff0c;本博客所执行的C标准均为C11. static成员和成员函数 对于特定类型的全体对象而言&#xff0c;有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。 通常在C中使用全局变量来实现&#xff0c;如果我们…

大模型和ollama一起打包到一个docker镜像中

如何将大模型镜像和 Ollama 镜像打包在一个 Docker 镜像中 最近工作中有个需求是将ollama和大模型一起打成一个镜像部署&#xff0c;将自己的操作步骤分享给大家。将大模型与 Ollama 服务打包在同一个 Docker 镜像中&#xff0c;可以简化部署流程并确保环境一致性。下面详细介…

2025年渗透测试面试题总结-攻防研究员(应用安全)(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 攻防研究员(应用安全) 一、基础部分 1. HTTP状态码对比 2. HTTP请求方法核心作用 3. 网络分层协议速查表…

SpringBoot新闻项目学习day3--后台权限的增删改查以及权限管理分配

新增管理员修改管理员删除管理员登录 新增管理员 1.点击新增按钮打开一个对话框 2.确定新增对话框要显示哪些内容 3.提交 4.后端处理、保存 5.响应前端 vue代码 <template><!-- 新增代码内容是比较多的,建议抽取出来,定义到一个独立的vue文件中在列表组件中导入…

算法导论第二十五章 深度学习的伦理与社会影响

第二十五章 深度学习的伦理与社会影响 技术的光芒不应掩盖伦理的阴影 随着深度学习技术在各领域的广泛应用&#xff0c;其引发的伦理和社会问题日益凸显。本章将深入探讨这些挑战&#xff0c;并提供技术解决方案和最佳实践&#xff0c;引导读者构建负责任的人工智能系统。 25.…

Linux中ansible模块补充和playbook讲解

一、模块使用 1.1 Yum模块 功能&#xff1a;管理软件包&#xff0c;只支持RHEL&#xff0c;CentOS&#xff0c;fedora&#xff0c;不支持Ubuntu其它版本 参数说明name要操作的软件包名称&#xff0c;支持通配符&#xff08;如 httpd, nginx*&#xff09;&#xff0c;也可以是…

唐代大模型:智能重构下的盛世文明图谱

引言&#xff1a;当长安城遇见深度学习 一件唐代鎏金舞马衔杯银壶的虚拟复原品正通过全息投影技术演绎盛唐乐舞。这个跨越时空的场景&#xff0c;恰似唐代大模型技术的隐喻——以人工智能为纽带&#xff0c;连接起长安城的盛世气象与数字时代的文明重构。作为人工智能与历史学…