从迭代器到生成器:小内存也能处理大数据

有的对象可以用for循环比如字符串和列表,有的对象不可以比如整数

my_str = '123'
for s in my_str;print(s)my_lst = [1,2,3]
for i in my_lst:print(i)my_int = 123
for n in my_int:print(n) # 报错

python中能够使用for循环迭代的对象叫可迭代对象也叫iterables
iterables包含__iter__方法,我们开头通过hasattr这个函数查看某一个对象是否有某个属性或者方法

print(hasattr(my_str,'__iter__')) #True
print(hasattr(my_lst,'__iter__')) #True
print(hasattr(my_int,'__iter__')) #False

像__iter__这样前后有两个下划线的方法叫特殊方法,也叫魔法方法,一般用来控制对象要怎么回应Python的内置行为,那么__iter__这个方法可以做什么呢? 为什么有了它 就可以在for循环中进行迭代?这跟for循环的原理有关

在这里插入图片描述

it = iter(my_str) # my_str.__iter__() 这样是等价的
while True:try:print(next(it))except StopIteration:break

什么是迭代器,先给出迭代器的定义:
迭代器需要包含两个魔法方法: __iter__,__next__ 可以说只要包含了这两个方法的对象就是迭代器,这两个方法用来做什么?iter()就会返回一个迭代器
迭代器的iter就会返回迭代器本身,对于next每次调用都要获取下一个迭代器的值,特点是一直往下走,不会回头,直到没有下一个值时raise 一个 stopiteration异常,此时迭代器就用完了,我们就不能再从这个迭代器中获取值了,如果我们还想用,需要对可迭代对象重新调用iter,创建一个新的迭代器.

实际例子: 假设有一个伪造了10万行数据的logfile.log文件

def process_line(line):pass # 这里不是重点
import tracemalloc # 引入内置模块跟踪程序内存使用情况
tracemallic.start()
filepath = './logfile.log'
with open(filepath,'r') as f:lines = f.readlines() #全部读取以列表的形式存在变量中
for line in lines:process_line(line)
# 将文件内容都存在于内存中,毫无疑问内存占用会相当大
current,peak = tracemalloc.get_traced_memory()
print(f"Cuurent memory usage:{current / 1024**2} MB")
print(f'peak memory usage:{peak  / 1024**2 }MB') #10MB
tracemalloc.stop() 

可以一行行处理:

class LineIterator:def __init__(self,filepath):self.file = open(filepath,'r')def __iter__(self):return selfdef __next__(self):line = self.file.readline()if line:return lineelse:self.file.close()raise StopIteration
line_iter = LineIterator(filepath)
for line in line_iter:process_line(line) 
# 结果不到0.1MB 因为我们并没有把文件内容加载到内存中

理解了迭代器的内部构造之后
我不想处理所有的行,我只想处理操作类型是create的行
在这里插入图片描述

def __next__(self):line = self.file.readline()while line:if line.split('|')[2].strip() == 'Create':return lineline = self.file.readline()self.file.close()raise StopIteration

从这里我们就可以看出迭代器最重要的部分是next方法,init和iter更像是一个累赘,如果你有这种感觉,那么有一个好消息Python有一个东西叫做生成器可以理解为迭代器的简单实现,生成器有两种写法,分别是生成器函数和生成器表达式,在这里只会提及生成器函数

这是一个简单的生成器函数,这个函数在调用时不会返回具体的值而是返回一个生成器.
生成器函数会包含yield的关键字,通过这个关键字,生成器会自动产生__iter____next__方法,它的运行规则是,在yield的这行产生一个值然后退出函数,下次进来时又从yield处继续,这里有两行打印函数方便我们观察,与迭代器相同我们可以通过next和for查看值

def generator(n):for i in range(n):print('before yield')yield iprint('after yield')gen = generator(3)
print(next(gen))
print('___')
for i in gen:print(i)

before yield
0


after yield
before yield
1
after yield
before yield
2
after yield

我们可以更改上面那个文件的代码:

def line_generator(filepath):with open(filepath,'r') as file:for line in file:if line.split('|')[2].strip() == 'Create':yield lineelse:continue
line_gen = line_generator(filepath)
for line in line_gen:process_line(line)

可想而知,这个内存也极小
好处: 惰性计算 很好节省内存资源 生成可以没有尽头
斐波那契为例子:

def fib_generator():cur,nxt = 0,1while True:yield curcur,next = nxt,cur+nxt
fib_gen = fib_generator()
for _ in range(10):print(next(fib_gen))
# 

一道简单的题目:

# 生成器函数小练习
def multiplcation_generator(x):for i in range(1,10):yield i*xmulti_gen = multiplcation_generator(2)
print(next(multi_gen)) #2
print(next(multi_gen)) #4
print(next(multi_gen)) #6
print(next(multi_gen)) #8

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

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

相关文章

第29天:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作

时间轴: 演示案例: JS 原生开发-DOM 树-用户交互 DOM:文档操作对象 浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈 安全问题:本身的前端代码通过 DOM 技术实现代码的更新修改&#xff…

“蜀道山”高校联合公益赛 Web (部分)

文章目录 奶龙牌WAF海关警察训练平台恶意代码检测器 奶龙牌WAF <?php if ($_SERVER[REQUEST_METHOD] POST && isset($_FILES[upload_file])) {$file $_FILES[upload_file];if ($file[error] UPLOAD_ERR_OK) {$name isset($_GET[name]) ? $_GET[name] : basen…

docker-compose搭建xxl-job、mysql

docker-compose搭建xxl-job、mysql 1、搭建docker以及docker-compose2、下载xxl-job需要数据库脚本3、创建文件夹以及docker-compose文件4、坑来了5、正确配置6、验证-运行成功 1、搭建docker以及docker-compose 略 2、下载xxl-job需要数据库脚本 下载地址&#xff1a;https…

XML JSON

XML 与 JSON 结构 XML&#xff08;eXtensible Markup Language&#xff09; 1. 定义 XML 是一种标记语言&#xff0c;用于描述数据的结构和内容。主要用于数据存储与交换。 2. 特点 可扩展性&#xff1a;用户可以自定义标签。层次化结构&#xff1a;数据以树形结构组织&…

【Innodb阅读笔记】之 二进制文件应用,主从复制搭建

一、概述 MySQL的主从复制&#xff08;Master-Slave Replication&#xff09;是一种数据复制解决方案&#xff0c;将主数据库的DDL和DML操作通过二进制日志传到从库服务器中&#xff0c;然后在从库上对这些日志重新执行&#xff08;也叫重做&#xff09;&#xff0c;从而是的从…

如何制作项目网页

一、背景 许多论文里经常会有这样一句话Supplementary material can be found at https://hri-eu.github.io/Lami/&#xff0c;这个就是将论文中的内容或者补充视频放到一个网页上&#xff0c;以更好的展示他们的工作。因此&#xff0c;这里介绍下如何使用前人提供的模板制作我…

Spring:Spring事务管理代码案例讲解

Spring事务管理知识讲解请见&#xff1a;Spring事务知识点讲解 下面演示一个代码示例进行理解。 需求 两个账户相互转账&#xff0c;并记录日志&#xff0c;即使有转账失败也要记录 需求分析 这里主要是需要开启事务机制来控制转入和转出&#xff1a; 1&#xff0c;创建一…

了解网络威胁情报:全面概述

网络威胁情报 CTI 是指系统地收集和分析与威胁相关的数据&#xff0c;以提供可操作的见解&#xff0c;从而增强组织的网络安全防御和决策过程。 在数字威胁不断演变的时代&#xff0c;了解网络威胁情报对于组织来说至关重要。复杂网络攻击的兴起凸显了制定强有力的策略以保护敏…

Scrapy图解工作流程-cnblog

1.1 介绍部分&#xff1a; 文字提到常用的Web框架有Django和Flask&#xff0c;接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分&#xff1a; Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…

【ArcGISPro】Sentinel-2数据处理

错误 默认拉进去只组织了4个波段,但是实际有12个波段 解决方案 数据下载 Sentinel-2 数据下载-CSDN博客 数据处理 数据查看 创建镶嵌数据集 在数据管理工具箱中找到创建镶嵌数据集

Python数据分析(OpenCV)

第一步通过pip安装依赖包&#xff0c;执行一下命令 pip install opencv-python 如果是Anaconda请在工具中自行下载 下载好咋们就可以在环境中使用了。 人脸识别的特征数据可以到 github上面下载&#xff0c;直接搜索OpenCV 然后我们在源码中通过cv2的级联分类器引入人脸的特征…

最小生成树-Prim与Kruskal算法

文章目录 什么是最小生成树&#xff1f;Prim算法求最小生成树Python实现&#xff1a; Kruskal算法求最小生成树并查集 Python实现&#xff1a; Reference 什么是最小生成树&#xff1f; 在图论中&#xff0c;树是图的一种&#xff0c;无法构成闭合回路的节点-边连接组合称之为…

深入理解 Java 基本语法之数组

目录 一、数组基础概念 二、数组的声明 1. 基本数据类型数组声明&#xff1a; 2. 引用数据类型数组声明&#xff1a; 三、数组的创建 四、数组的初始化 五、数组的使用 ​编辑1. 获取长度以及访问元素&#xff1a; 2. 数组作为方法的参数&#xff1a; 3. 数组作为方法…

计算机毕业设计PySpark+Scrapy农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

17. C++模板(template)1(泛型编程,函数模板,类模板)

⭐本篇重点&#xff1a;泛型编程&#xff0c;函数模板&#xff0c;类模板 ⭐本篇代码&#xff1a;c学习/07.函数模板 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. 泛型编程 二. 函数模板 2.1 函数模板的格式 2.2 函数模板的简单使用 2.3 函数模板…

Jupyter Notebook的安装和配置提示功能

Python开发环境搭建conda管理环境-CSDN博客 安装anaconda和对接到编译器的教程可以看上面这一篇 Jupyter Notebook是一种交互式计算环境&#xff0c;它允许用户在单个文档中编写和执行代码、方程、可视化和文本。与其他编译器相比&#xff0c;Jupyter Notebook的突出点在于其交…

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地&#xff08;只有第一次需要&#xff09; git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…

剑指Offer26.树的子结构

题目让判断B是不是A的子结构 但是我们进行判断是基于 两个树的根相等时, 去判断是否为子结构 针是否等于B的根节点的值对A做先序遍历的过程中 如果根节点相同我们去判断此时B是不是以该根节点的子树的子结构! 实际上进行先序遍历的同时要进行递归判断子结构 B是不是A节点的子结…

2024御网杯信息安全大赛个人赛wp(misc方向)

目录 一.信息安全大赛的通知二、编码转换1. 第一部分2. 第二部分3. 第三部分 三、1.txt四、buletooth 题目附件以及工具链接&#xff1a; 通过网盘分享的文件&#xff1a;御网杯附件 链接: https://pan.baidu.com/s/1LNA6Xz6eZodSV0Io9jGSZg 提取码: jay1 –来自百度网盘超级会…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…