当前位置: 首页 > news >正文

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

安装包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Ru7HhTSotz9mteHug-Yhpw?pwd6666 提取码&#xff1a;6666 双击安装包&#xff0c;一直下一步。 配置环境变量&#xff1a; 先配置系统变量中的path&#xff1a; 接着配置用户变量&#xff1a; 在 cmd 中输入…...

Mac电脑BIM建模软件 Archicad 26 for Mac最新

ARCHICAD 软件特色 智能化 在2D CAD中&#xff0c;所有的建筑构件都由线条构成和表现&#xff0c;仅仅是一些线条的组合而已&#xff0c;当我们阅读图纸的时候是按照制图规范来读取这些信息。我们用一组线条表示平面中的窗&#xff0c;再用另一组不同的线条在立面中表示同一个…...

JavaEE-网络编程套接字(UDP/TCP)

下面写一个简单的UDP客户端服务器流程 思路&#xff1a; 对于服务器端&#xff1a;读取请求&#xff0c;并解析–> 根据解析出的请求&#xff0c;做出响应(这里是一个回显&#xff0c;)–>把响应写回客户端 对于客户端&#xff1a;从控制台读取用户输入的内容–>从控制…...

微服务技术栈-Gateway服务网关

文章目录 前言一、为什么需要网关二、Spring Cloud Gateway三、断言工厂和过滤器1.断言工厂2.过滤器3.全局过滤器4.过滤器执行顺序 四、跨域问题总结 前言 在之前的文章中我们已经介绍了微服务技术中eureka、nacos、ribbon、Feign这几个组件&#xff0c;接下来将介绍另外一个组…...

函数形状有几种定义方式;操作符infer的作用

在 TypeScript 中&#xff0c;函数形状可以用多种方式进行定义。下面介绍了几种常用的函数形状定义方式&#xff1a; 函数声明&#xff1a; function add(a: number, b: number): number {return a b; }在函数声明中&#xff0c;我们直接使用 function 关键字来声明函数&…...

Java / MybatisPlus:JSON处理器的应用,在实体对象中设置对象属性,对象嵌套对象

1、数据库设计 2、定义内部的实体类 /*** Author lgz* Description* Date 2023/9/30.*/ Data // 静态构造staticName&#xff0c;方便构造对象并赋予属性 AllArgsConstructor(staticName "of") NoArgsConstructor ApiModel(value "亲友", description …...

力扣 -- 1027. 最长等差数列

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int longestArithSeqLength(vector<int>& nums) {int nnums.size();int ret2;unordered_map<int,int> hash;//这里可以先把nums[0]存进哈希表中&#xff0c;方便后面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 创建工程步骤 选择&#xff1a;Create a new Xcode project选择&#xff1a;iOS-> single View App填写&#xff1a; project name: swift-app-helloidentifer: smile 包名language: s…...

零基础部署nginx mysql springboot

参考&#xff1a;写给开发人员看的Docker干货&#xff0c;零基础部署nginx mysql springboot 一、连接linux 阿里云 参考&#xff1a;部署到Linux 可能需要购买&#xff1a;购买链接 二、安装docker # 先切换到root用户下 sudo su# 更新apt-get&#xff0c;保证apt-get最新…...

6-3 模式匹配

description 给出主串s和模式串t&#xff0c;其长度均不超过1000。本题要求实现一个函数BF(string s, string t)&#xff0c;求出模式串t在主串s中第一次出现的位置&#xff08;从0开始计算&#xff09;&#xff0c;如果在s中找不到t&#xff0c;则输出-1。 函数接口定义&…...

SQL JOIN 时 USING 和 ON 的异同

在数据表做 join 时&#xff0c;即可以用 using&#xff0c;也可以用 on。有什么异同点呢。 ON 是更加普遍的用法&#xff0c;可以连接表 On 一个字段&#xff0c;多个字段&#xff0c;甚至一个条件表达式。举例 SELECT * FROM world.City JOIN world.Country ON (City.Cou…...

安全学习_开发相关_JNDI介绍(注入)RMILDAP服务

文章目录 参考&本节目的JNDI概念-RMI&LDAP服务调用检索&#xff1a;在RMI服务中调用了InitialContext.lookup()的常用类有&#xff1a;在LDAP服务中调用了InitialContext.lookup()的常用类有&#xff1a; JNDI注入-使用工具生成远程调用JNDI远程调用-工具&#xff08;j…...

C#学生选课及成绩查询系统

一、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分&#xff0c;传统的人工管理档案的方式存在着很多的缺点&#xff0c;如&#xff1a;效率低、保密性差等&#xff0c;所以开发一套综合教务系统管理软件很有必要&#xff0c;它应该具有传统的手工管理所无法比拟的…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...