Day 20:【99天精通Python】迭代器与生成器 - 内存优化的黑科技

Day 20:【99天精通Python】迭代器与生成器 - 内存优化的黑科技

前言

欢迎来到第20天!

在处理数据时,我们经常会遇到这样的场景:需要处理一个几 GB 甚至几 TB 的大文件,或者需要生成一个包含 1 亿个数字的列表。
如果直接把所有数据一次性加载到内存中(比如用列表),电脑内存瞬间就会爆满,程序卡死。

Python 给我们提供了一套优雅的解决方案:迭代器 (Iterator)生成器 (Generator)。它们的核心思想是:“用一个,拿一个”,而不是**“一次性全拿出来”**。这就像是流水线作业,既节省内存,又提高了效率。

本节内容:

  • 可迭代对象 (Iterable) vs 迭代器 (Iterator)
  • for循环的本质
  • yield关键字详解
  • 生成器函数与生成器表达式
  • 实战:斐波那契数列与大文件读取

一、迭代器:按需获取

1.1 什么是可迭代对象 (Iterable)?

简单说,凡是能用for循环遍历的东西,都是可迭代对象。
例如:列表、元组、字符串、字典、集合。

fromcollections.abcimportIterableprint(isinstance([],Iterable))# Trueprint(isinstance("abc",Iterable))# Trueprint(isinstance(100,Iterable))# False (整数不可迭代)

1.2 什么是迭代器 (Iterator)?

迭代器是一个"更高级"的对象,它不仅可以被遍历,还记录了当前访问到了哪里
它必须实现两个方法:

  1. __iter__(): 返回迭代器对象本身。
  2. __next__(): 返回下一个元素。如果没有元素了,抛出StopIteration异常。

1.3 iter() 和 next()

我们可以用iter()函数把一个列表变成迭代器。

nums=[1,2,3]it=iter(nums)# 创建迭代器print(next(it))# 1print(next(it))# 2print(next(it))# 3# print(next(it)) # 报错: StopIteration

1.4 for 循环的本质

其实for循环内部就是在做这件事:

  1. 调用iter(obj)获取迭代器。
  2. 不断调用next(it)获取元素。
  3. 遇到StopIteration异常时,停止循环。

二、生成器 (Generator):最简单的迭代器

手动写一个迭代器类太麻烦了(需要写__iter____next__)。Python 提供了生成器,让你用写函数的语法来实现迭代器。

2.1 yield 关键字

yield的作用类似于return,但它不会结束函数,而是暂停函数,并保存当前的状态。下次调用next()时,函数会从暂停的地方继续执行。

defmy_generator():print("开始生成...")yield1print("暂停回来,继续生成...")yield2print("最后一次...")yield3gen=my_generator()# 此时函数并没有执行!只有调用 next() 才会动。print(next(gen))# 输出:# 开始生成...# 1print(next(gen))# 输出:# 暂停回来,继续生成...# 2

2.2 生成器表达式

类似于列表推导式,只是把方括号[]换成了圆括号()

# 列表推导式 (立即生成所有数据,占内存)list_data=[x**2forxinrange(10)]print(list_data)# [0, 1, 4, ..., 81]# 生成器表达式 (不生成数据,只保存算法,省内存)gen_data=(x**2forxinrange(10))print(gen_data)# <generator object ...># 必须遍历才能取值fornumingen_data:print(num,end=" ")

三、生成器 vs 列表:性能对比

假设我们要处理 1000 万个数字。

importsys# 方式1:列表# 瞬间占用大量内存big_list=[xforxinrange(10000000)]print(f"列表占用内存:{sys.getsizeof(big_list)/1024/1024:.2f}MB")# 结果约 380 MB# 方式2:生成器# 几乎不占内存big_gen=(xforxinrange(10000000))print(f"生成器占用内存:{sys.getsizeof(big_gen)}Bytes")# 结果只有 100多 Bytes (无论数据多大,它都只占这么多)

结论:处理海量数据时,必须使用生成器。


四、实战练习

练习1:斐波那契数列生成器

斐波那契数列:1, 1, 2, 3, 5, 8, 13…
如果用递归算第100位会卡死,用生成器则轻松秒杀。

deffib_generator(n):"""生成前 n 个斐波那契数"""a,b=0,1count=0whilecount<n:yieldb# 产出当前数值a,b=b,a+b count+=1# 打印前10个fornuminfib_generator(10):print(num,end=" ")# 1 1 2 3 5 8 13 21 34 55

练习2:大文件读取器

假设有一个 10GB 的日志文件,每行一条日志。我们需要查找包含 “ERROR” 的行。
直接readlines()会内存溢出,我们用生成器逐行读取。

defread_large_file(filename):"""生成器:每次只读一行"""withopen(filename,"r",encoding="utf-8")asf:forlineinf:yieldline# 暂停,把行给出去# 使用# 假设 log.txt 存在# for line in read_large_file("log.txt"):# if "ERROR" in line:# print(f"发现错误: {line.strip()}")

:其实 Python 的文件对象本身就是可迭代的,直接for line in f效果也是一样的,这里只是为了演示原理。


五、深入理解:send() 方法

生成器不仅可以产出数据 (yieldout),还可以接收数据 (yieldin)。

defeater():print("准备吃饭...")whileTrue:food=yield# 接收外部传进来的值print(f"吃了{food}")e=eater()next(e)# 预激生成器 (执行到第一个 yield 并暂停)e.send("包子")# 吃了 包子e.send("面条")# 吃了 面条e.close()# 关闭生成器

这是协程 (Coroutine)的雏形,也是 Python 异步编程 (async/await) 的基石。


六、常见问题

Q1:生成器能遍历第二次吗?

不能。生成器是"一次性"的。遍历完一遍后,指针就在最后了,再调用next()会抛错。如果需要再次遍历,必须重新创建生成器对象。

Q2:return在生成器里起什么作用?

在生成器函数中,return等同于抛出StopIteration异常,用于终止生成。


七、小结

迭代 Iteration

Iterable (可迭代对象)

Iterator (迭代器)

列表, 字符串...

实现了iter

实现了iternext

next() 取值

只能往前,不能回头

Generator (生成器)

函数中包含 yield

生成器表达式 (x for x in ...)

省内存,惰性计算

关键要点

  1. Iterable是原材料,Iterator是流水线。
  2. 生成器是最简单的迭代器写法。
  3. yield是暂停键,next是播放键。
  4. 处理大量数据时,优先考虑生成器。

八、课后作业

  1. 自定义 range:编写一个生成器函数my_range(start, end, step),模仿 Python 内置range的功能(支持浮点数步长)。
  2. 素数生成器:编写一个生成器,无限生成素数(2, 3, 5, 7…)。并在外部循环中打印前 20 个素数。
  3. 日志清洗:模拟一个包含脏数据的列表data = ["info: ok", "error: fail", None, "", "warn: check"]。编写一个生成器,清洗掉None和空字符串,并统一转换为大写。

下节预告

Day 21:基础篇总结与综合实战- 恭喜!你已经完成了 Python 基础篇的所有核心内容。明天我们将通过一个综合性的图书管理系统项目,把这20天的知识串联起来!


系列导航

  • 上一篇:Day 19 - 装饰器
  • 下一篇:Day 21 - 基础篇总结与实战(待更新)

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

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

相关文章

ResNet18实战教程:农业作物识别系统搭建

ResNet18实战教程&#xff1a;农业作物识别系统搭建 1. 引言 1.1 学习目标 本文将带你从零开始&#xff0c;基于 TorchVision 官方 ResNet-18 模型&#xff0c;搭建一个具备通用物体识别能力的图像分类系统&#xff0c;并进一步扩展为适用于农业场景的作物识别系统原型。你将…

ResNet18技术揭秘:轻量级模型设计哲学

ResNet18技术揭秘&#xff1a;轻量级模型设计哲学 1. 引言&#xff1a;通用物体识别中的ResNet-18价值定位 在深度学习推动计算机视觉飞速发展的进程中&#xff0c;图像分类作为最基础也最关键的感知任务之一&#xff0c;始终是智能系统“看懂世界”的第一步。尽管近年来更复…

01.学习预备

一. 笔记查看方式 视图 -> 文档结构图 & Web版式视图. 去除拼写检查.这样的拼写检查的波浪线会影响我们的文档美观和影响我们的阅读,所以可以把拼写检查禁用掉,如下:隐藏段落标志. 如下红框中的符号为"段落标志":安装360健康护士,开启视力保护色,这样看文档或…

ResNet18部署优化:模型并行推理技术

ResNet18部署优化&#xff1a;模型并行推理技术 1. 背景与挑战&#xff1a;通用物体识别中的效率瓶颈 在当前AI应用广泛落地的背景下&#xff0c;通用物体识别已成为智能监控、内容审核、辅助驾驶等场景的核心能力。基于ImageNet预训练的ResNet-18因其结构简洁、精度适中、参…

ResNet18部署案例:智能家居控制中心

ResNet18部署案例&#xff1a;智能家居控制中心 1. 引言&#xff1a;通用物体识别在智能场景中的核心价值 随着智能家居设备的普及&#xff0c;用户对环境感知能力的需求日益增长。传统的规则化控制系统难以应对复杂多变的家庭场景&#xff0c;而引入AI视觉识别技术则为“理解…

详解PCB板生产厂家在样板打样阶段的配套支持

当你的PCB设计“第一次就成功”&#xff1a;揭秘高配支持的样板打样伙伴你有没有过这样的经历&#xff1f;熬夜画完原理图、反复优化布线&#xff0c;终于导出Gerber文件&#xff0c;满怀期待地发给板厂——结果三天后收到一封邮件&#xff1a;“BGA焊盘阻焊桥不足&#xff0c;…

ResNet18实战:无人机航拍图像分析系统搭建

ResNet18实战&#xff1a;无人机航拍图像分析系统搭建 1. 引言&#xff1a;通用物体识别的工程价值与ResNet-18的定位 随着无人机在农业监测、城市规划、灾害评估等领域的广泛应用&#xff0c;实时、准确的航拍图像分析能力成为关键需求。传统图像处理方法难以应对复杂多变的…

ResNet18实战教程:多场景物体识别应用开发

ResNet18实战教程&#xff1a;多场景物体识别应用开发 1. 引言&#xff1a;通用物体识别中的ResNet18价值 在计算机视觉领域&#xff0c;通用物体识别是构建智能系统的基础能力之一。无论是自动驾驶感知环境、智能家居理解用户行为&#xff0c;还是内容平台自动打标&#xff…

ResNet18性能对比:ResNet18 vs ResNet50实测

ResNet18性能对比&#xff1a;ResNet18 vs ResNet50实测 1. 引言&#xff1a;为何进行ResNet18与ResNet50的实测对比&#xff1f; 在深度学习图像分类任务中&#xff0c;ResNet&#xff08;残差网络&#xff09; 系列模型因其出色的性能和稳定的训练表现&#xff0c;成为工业…

TheIsle恐龙岛巨龙服1.53服务器搭建代码

服务器系统选择Windows&#xff0c;系统版本2012或以上&#xff0c;推荐系统&#xff1a;Windows Server 2022 Datacenter。 不管是物理机还是云服务器&#xff0c;都需要开放以下TCP和UDP端口&#xff1a; 7777-7778 27015-27017 第一步&#xff1a;新建文件夹&#xff0c;命…

ResNet18实战指南:医疗影像预处理技巧

ResNet18实战指南&#xff1a;医疗影像预处理技巧 1. 引言&#xff1a;通用物体识别与ResNet-18的工程价值 在深度学习推动下&#xff0c;图像分类技术已广泛应用于智能安防、内容推荐和医疗辅助诊断等领域。其中&#xff0c;ResNet-18 作为残差网络&#xff08;Residual Net…

Multisim14与NI Ultiboard联合设计中的元器件匹配问题解析

从原理图到PCB&#xff1a;Multisim14与NI Ultiboard元器件匹配的“坑”与破局之道你有没有遇到过这种情况&#xff1f;花了一整天精心画好电路原理图&#xff0c;信心满满地点击“Transfer to Ultiboard”&#xff0c;结果弹出一行红字警告&#xff1a;“Footprint not found …

ResNet18部署避坑指南:常见错误及解决方案

ResNet18部署避坑指南&#xff1a;常见错误及解决方案 1. 引言&#xff1a;通用物体识别中的ResNet-18价值 在当前AI应用快速落地的背景下&#xff0c;通用图像分类已成为智能监控、内容审核、辅助搜索等场景的基础能力。其中&#xff0c;ResNet-18作为深度残差网络中最轻量且…

ResNet18性能测试:不同光照条件下的识别效果

ResNet18性能测试&#xff1a;不同光照条件下的识别效果 1. 引言&#xff1a;通用物体识别中的ResNet-18 在计算机视觉领域&#xff0c;通用物体识别是构建智能系统的基础能力之一。无论是自动驾驶感知环境、安防监控识别异常行为&#xff0c;还是智能家居理解用户场景&#…

【阅读笔记】Bayer阵列坏点校正-《Adaptive pixel defect correction》

一、背景 本文提出了一种相对简单的缺陷校正算法&#xff0c;仅需77的原始彩色滤光片阵列数据核即可有效校正多种缺陷类型。该自适应边缘算法具有高质量、占用图像行数少、适应性强且独立于其他板载DSP算法的特点。实验结果表明&#xff0c;相较于传统一维校正方法&#xff0c…

数字时钟电路设计:基于Multisim仿真电路图的新手教程

从零搭建数字时钟&#xff1a;基于Multisim的全流程实战指南你有没有试过在面包板上搭一个数字时钟&#xff0c;结果接通电源后数码管乱闪、计数跳变、秒针飞奔&#xff1f;别担心&#xff0c;这几乎是每个电子初学者都会踩的坑。而今天我们要走一条更聪明的路——先仿真&#…

【随笔】十年之约,不止约定十年

1、何为“十年之约” 十年之约是一个个人博客收录网站&#xff0c;其slogan是** 一个人的寂寞&#xff0c;一群人的狂欢。** 『十年之约』是由『十年之约』项目组维护的非营利性、面向个人独立博客自愿加入的博客活动。希望通过『十年之约』能锻炼您的写作能力&#xff0c;进而…

ResNet18技术揭秘:为何成为经典CNN架构

ResNet18技术揭秘&#xff1a;为何成为经典CNN架构 1. 引言&#xff1a;通用物体识别中的ResNet18 在计算机视觉的发展历程中&#xff0c;图像分类是基础且关键的任务之一。从早期的LeNet到AlexNet、VGG&#xff0c;卷积神经网络&#xff08;CNN&#xff09;不断演进&#xf…

项目应用中Vivado 2023.1多用户License管理策略

Vivado 2023.1多用户License管理实战&#xff1a;如何让有限授权支撑整个FPGA团队高效运转&#xff1f; 在一次跨部门FPGA联合开发项目中&#xff0c;我们团队遭遇了这样一个典型场景&#xff1a;早上9点刚过&#xff0c;三位工程师几乎同时点击“Run Implementation”——布局…

ResNet18入门指南:快速理解1000类分类

ResNet18入门指南&#xff1a;快速理解1000类分类 1. 引言&#xff1a;通用物体识别中的ResNet18 在计算机视觉领域&#xff0c;图像分类是基础且关键的任务之一。从智能相册自动打标签&#xff0c;到自动驾驶系统识别道路环境&#xff0c;背后都离不开强大的图像分类模型。其…