Python生成器
生成器 Generators
要理解生成器,首先要理解迭代器,迭代器由以下三个部分组成:
- 可迭代对象(iterable)
- 迭代器(iterator)
- 迭代(iteration)
1. 可迭代对象
只要定义了可以返回一个迭代器的__iter__方法的对象,或者定义了可以支持下标索引的__getitem__方法。
2. 迭代器
只要定义了一个__next__方法的对象。
3. 迭代
从某个地⽅(⽐如⼀个列表)取出⼀个元素的过程。当我们使⽤⼀个循环来遍历某个东西时,这就叫⼀个迭代。
生成器
生成器也是一种迭代器,但是只能对其迭代一次。因为生成器没有把所有的值存在内存中,而是在运行时生成值(lazy)。可以通过遍历来使用它们,使用for循环或传递给任意可以进行迭代的函数和结构。
大多数生成器是以函数来实现的,它们并不返回一个值,而是yield一个值。

生成器最好的使用场景是:不需要一次将所有计算的结果全部放在内存中,或者一次读出全部的原始数据,这样会造成很大的内存占用。
上述例子中,我们用for循环来迭代这个生成器函数,同样,我们可以使用python的next()函数来获得迭代器的下一个元素。

基础数据类型list和str都是可迭代对象,我们经常会使用for循环来获得每一个下标的数据。

但是我们发现,不能调用next来迭代字符串和数据,这是因为:
数组和字符串是可迭代对象,但不是迭代器。
使用for关键字迭代可迭代对象时,for会自动获取到迭代器,进行迭代。但是next只能对迭代器进行迭代,因此我们需要使用到iter()函数来根据一个可迭代对象返回一个迭代器对象!

同时,next方法没有实现对StopIteration异常的捕捉,在自己写的迭代器内一般需要额外进行迭代结束的编写。
测验:
现在我们要写一个生成器,迭代一个数组的时候,不再是按顺序取出而是隔一个元素取出。
1. 函数式迭代器(yield)
def skip_elements(arr):for i in range(0, len(arr), 2): # 从索引0开始,每次跨越2个元素yield arr[i]my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
gen = skip_elements(my_list)for element in gen:print(element)
2. 编写一个迭代器:
class SkipElementsGenerator:def __init__(self, arr):self.arr = arrself.index = 0def __iter__(self):return selfdef __next__(self):if self.index >= len(self.arr):raise StopIterationelement = self.arr[self.index]self.index += 2 # 每次跳过一个元素return elementmy_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
gen = SkipElementsGenerator(my_list)for element in gen:print(element)
SkipElementsGenerator是一个迭代器,我们直接将要迭代的数组当成形参丢入以初始化迭代器。
注意:因为要用for迭代迭代器,因此迭代器也必须得是可迭代对象,这里只需要简单实现__iter__函数并且返回self即可!
Another Way
比较直观了解可迭代对象与迭代器的例子:
class MyArray:def __init__(self, arr):self.arr = arrdef __iter__(self):return SkipElementsGenerator(self.arr)class SkipElementsGenerator:def __init__(self, arr):self.arr = arrself.index = 0def __next__(self):if self.index >= len(self.arr):raise StopIterationelement = self.arr[self.index]self.index += 2 # 每次跳过一个元素return element# 创建自定义数组对象
my_list = MyArray([1, 2, 3, 4, 5, 6, 7, 8, 9])# 使用生成器迭代元素
for element in my_list:print(element)
原始数据是可迭代对象,实现__iter__方法,返回它的迭代器。
迭代器实现__next__方法,迭代返回每一次迭代的值。
这个时候for循环直接迭代可迭代对象,不像上一个例子一样是迭代迭代器。
for循环是先找到可迭代对象的迭代器! 通过__iter__方法!
然后对迭代器进行迭代! 通过迭代器的__next__方法!
这样写的话可以实现函数的解耦,不会像上面代码一样,还要实例化迭代器gen = SkipElementsGenerator(my_list),然后人为迭代迭代器。
这样写的话,只需要像原来一个,实例化自定义的数据类型,直接用for或者iter来获得迭代器,代码中不会出现迭代器的名字,无感使用。
相关文章:
Python生成器
生成器 Generators 要理解生成器,首先要理解迭代器,迭代器由以下三个部分组成: 可迭代对象(iterable)迭代器(iterator)迭代(iteration) 1. 可迭代对象 只要定义了可以…...
flutter开发实战-使用FutureBuilder异步数据更新Widget
flutter开发实战-使用FutureBuilder异步数据更新Widget 在开发过程中,经常遇到需要依赖异步数据更新Widget的情况,如下载图片后显示Widget,获取到某个数据时候,显示在对应的UI界面上,都可以使用FutureBuilder异步数据…...
1.2 数据模型
思维导图: 前言: **1.2.1 什么是模型** - **定义**:模型是对现实世界中某个对象特征的模拟和抽象。例如,一张地图、建筑设计沙盘或精致的航模飞机都可以视为具体的模型。 - **具体模型与现实生活**:具体模型可以很容…...
【实用工具】谷歌浏览器插件开发指南
谷歌浏览器插件开发指南涉及以下几个方面: 1. 开发环境准备:首先需要安装Chrome浏览器和开发者工具。进入Chrome应用商店,搜索“Extensions Reloader”和“Manifest Viewer”两个插件进行安装,这两个插件可以方便开发和调试。 2…...
应用层协议——DNS、DHCP、HTTP、FTP
目录 1、DNS 协议 1-1)Hosts 文件 1-2)DNS 系统 1-3)域名的组成、分类和树状结构 1-4)DNS 域名服务器类型 1-5)DNS 查询方式 1-6)DNS 域名解析的一般步骤 1-7)对象类型与资源记录 2、D…...
XML文件读写
0、.pro文件添加依赖 QT xml1、使用 QDomDocument 方式 #include <QtXml/QDomDocument> #include <QtXml/QDomProcessingInstruction> #include <QtXml/QDomElement> #include <QFile> #include <QTextStream> #include <QDebug>bo…...
Win11 安装 Vim
安装包: 链接:https://pan.baidu.com/s/1Ru7HhTSotz9mteHug-Yhpw?pwd6666 提取码:6666 双击安装包,一直下一步。 配置环境变量: 先配置系统变量中的path: 接着配置用户变量: 在 cmd 中输入…...
Mac电脑BIM建模软件 Archicad 26 for Mac最新
ARCHICAD 软件特色 智能化 在2D CAD中,所有的建筑构件都由线条构成和表现,仅仅是一些线条的组合而已,当我们阅读图纸的时候是按照制图规范来读取这些信息。我们用一组线条表示平面中的窗,再用另一组不同的线条在立面中表示同一个…...
JavaEE-网络编程套接字(UDP/TCP)
下面写一个简单的UDP客户端服务器流程 思路: 对于服务器端:读取请求,并解析–> 根据解析出的请求,做出响应(这里是一个回显,)–>把响应写回客户端 对于客户端:从控制台读取用户输入的内容–>从控制…...
微服务技术栈-Gateway服务网关
文章目录 前言一、为什么需要网关二、Spring Cloud Gateway三、断言工厂和过滤器1.断言工厂2.过滤器3.全局过滤器4.过滤器执行顺序 四、跨域问题总结 前言 在之前的文章中我们已经介绍了微服务技术中eureka、nacos、ribbon、Feign这几个组件,接下来将介绍另外一个组…...
函数形状有几种定义方式;操作符infer的作用
在 TypeScript 中,函数形状可以用多种方式进行定义。下面介绍了几种常用的函数形状定义方式: 函数声明: function add(a: number, b: number): number {return a b; }在函数声明中,我们直接使用 function 关键字来声明函数&…...
Java / MybatisPlus:JSON处理器的应用,在实体对象中设置对象属性,对象嵌套对象
1、数据库设计 2、定义内部的实体类 /*** Author lgz* Description* Date 2023/9/30.*/ Data // 静态构造staticName,方便构造对象并赋予属性 AllArgsConstructor(staticName "of") NoArgsConstructor ApiModel(value "亲友", description …...
力扣 -- 1027. 最长等差数列
解题步骤: 参考代码: class Solution { public:int longestArithSeqLength(vector<int>& nums) {int nnums.size();int ret2;unordered_map<int,int> hash;//这里可以先把nums[0]存进哈希表中,方便后面i从1开始遍历hash[num…...
正则验证用户名和跨域postmessage
正则验证用户名 字母数字符号大小写8-14匹配用户名的 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initial-scale1"><title>form</title> …...
jsbridge实战1:xcode swift 构建iOS app
[[toc]] 环境安装 macOs: 10.15.5 xcode: 11.6 demo:app 创建 hello world iOS app 创建工程步骤 选择:Create a new Xcode project选择:iOS-> single View App填写: project name: swift-app-helloidentifer: smile 包名language: s…...
零基础部署nginx mysql springboot
参考:写给开发人员看的Docker干货,零基础部署nginx mysql springboot 一、连接linux 阿里云 参考:部署到Linux 可能需要购买:购买链接 二、安装docker # 先切换到root用户下 sudo su# 更新apt-get,保证apt-get最新…...
6-3 模式匹配
description 给出主串s和模式串t,其长度均不超过1000。本题要求实现一个函数BF(string s, string t),求出模式串t在主串s中第一次出现的位置(从0开始计算),如果在s中找不到t,则输出-1。 函数接口定义&…...
SQL JOIN 时 USING 和 ON 的异同
在数据表做 join 时,即可以用 using,也可以用 on。有什么异同点呢。 ON 是更加普遍的用法,可以连接表 On 一个字段,多个字段,甚至一个条件表达式。举例 SELECT * FROM world.City JOIN world.Country ON (City.Cou…...
安全学习_开发相关_JNDI介绍(注入)RMILDAP服务
文章目录 参考&本节目的JNDI概念-RMI&LDAP服务调用检索:在RMI服务中调用了InitialContext.lookup()的常用类有:在LDAP服务中调用了InitialContext.lookup()的常用类有: JNDI注入-使用工具生成远程调用JNDI远程调用-工具(j…...
C#学生选课及成绩查询系统
一、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分,传统的人工管理档案的方式存在着很多的缺点,如:效率低、保密性差等,所以开发一套综合教务系统管理软件很有必要,它应该具有传统的手工管理所无法比拟的…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
