python哪些类型可以作为迭代器_Python教程|全面理解Python迭代器和生成器

2023-11-12

00e6f63e900272648992c8b8e8f5fe39.png

在Python中,很多对象都是可以通过for语句来直接遍历的,例如list、string、dict等等,这些对象都可以被称为可迭代对象。至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了。

迭代器

迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的iter()和next()方法。其中iter()方法返回迭代器对象本身;next()方法返回容器的下一个元素,在结尾时引发StopIteration异常。

iter()和next()方法

这两个方法是迭代器最基本的方法,一个用来获得迭代器对象,一个用来获取容器中的下一个元素。

对于可迭代对象,可以使用内建函数iter()来获取它的迭代器对象:6981857bb584be011374febb4388f112.png

例子中,通过iter()方法获得了list的迭代器对象,然后就可以通过next()方法来访问list中的元素了。当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器。

其实,当我们使用for语句的时候,for语句就会自动的通过iter()方法来获得迭代器对象,并且通过next()方法来获取下一个元素。

自定义迭代器

了解了迭代器协议之后,就可以自定义迭代器了。

下面例子中实现了一个MyRange的类型,这个类型中实现了iter()方法,通过这个方法返回对象本身作为迭代器对象;同时,实现了next()方法用来获取容器中的下一个元素,当没有可访问元素后,就抛出StopIteration异常。702efa8c04dd2c29a576df797b413ae3.png

这个自定义类型跟内建函数xrange很类似,看一下运行结果:e77a0e0aee6cce12488e9f066df8166a.png

3ca96d1cbf8d189e0a3f94c5237004ac.png

迭代器和可迭代对象

在上面的例子中,myRange这个对象就是一个可迭代对象,同时它本身也是一个迭代器对象。

看下面的代码,对于一个可迭代对象,如果它本身又是一个迭代器对象,就会有下面的 问题,就没有办法支持多次迭代。8913dc7eb6bfb5242234a3227aef191e.png

为了解决上面的问题,可以分别定义可迭代类型对象和迭代器类型对象;然后可迭代类型对象的iter()方法可以获得一个迭代器类型的对象。看下面的实现:4f5893a5b198d79bb50730871e41234f.png

代码的运行结果为:9ddc1c3d0df86be3dd3ebae3d24d2e05.png

其实,通过下面代码可以看出,list类型也是按照上面的方式,list本身是一个可迭代对象,通过iter()方法可以获得list的迭代器对象:eeeb4031bcd3fd030b7a4d98170c1715.png

生成器

在Python中,使用生成器可以很方便的支持迭代器协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。

也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。

下面看看生成器的使用:3ca78c0c23625b6a23e00eee2de44ea8.png

在这个例子中,定义了一个生成器函数,函数返回一个生成器对象,然后就可以通过for语句进行迭代访问了。

其实,生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,其中一个就是next()。如同迭代器一样,我们可以使用next()函数来获取下一个值。

生成器执行流程

下面就仔细看看生成器是怎么工作的。

从上面的例子也可以看到,生成器函数跟普通的函数是有很大差别的。

结合上面的例子我们加入一些打印信息,进一步看看生成器的执行流程:7202b4e1b5267013576fa3cfa5bfcf03.png

通过结果可以看到:当调用生成器函数的时候,函数只是返回了一个生成器对象,并没有 执行。

当next()方法第一次被调用的时候,生成器函数才开始执行,执行到yield语句处停止

next()方法的返回值就是yield语句处的参数(yielded value)

当继续调用next()方法的时候,函数将接着上一次停止的yield语句处继续执行,并到下一个yield处停止;如果后面没有yield就抛出StopIteration异常

生成器表达式

在开始介绍生成器表达式之前,先看看我们比较熟悉的列表解析( List comprehensions),列表解析一般都是下面的形式。[expr for iter_var in iterable if cond_expr]

迭代iterable里所有内容,每一次迭代后,把iterable里满足cond_expr条件的内容放到iter_var中,再在表达式expr中应该iter_var的内容,最后用表达式的计算值生成一个列表。

例如,生成一个list来保护50以内的所以奇数:[i for i in range(50) if i%2]

生成器表达式是在python2.4中引入的,当序列过长, 而每次只需要获取一个元素时,应当考虑使用生成器表达式而不是列表解析。生成器表达式的语法和列表解析一样,只不过生成器表达式是被()括起来的,而不是[],如下:(expr for iter_var in iterable if cond_expr)

看一个例子:eb6d589f7c2ec4ad6bf5ad9569a80d69.png

生成器表达式并不是创建一个列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目”产生”(yield)出来。 生成器表达式使用了”惰性计算”(lazy evaluation),只有在检索时才被赋值(evaluated),所以在列表比较长的情况下使用内存上更有效。

继续看一个例子:becbeb6f0654352c91e7be1624441ecb.png

从这个例子中可以看到,生成器表达式产生的生成器,它自身是一个可迭代对象,同时也是迭代器本身。

递归生成器

生成器可以向函数一样进行递归使用的,下面看一个简单的例子,对一个序列进行全排列:a2a978f13e468d1a4cd10b4103c76d39.png

代码的结果为:bcaaf6161a14ca52e68fde4d90ed2ad4.png

生成器的send()和close()方法

生成器中还有两个很重要的方法:send()和close()。send(value):

从前面了解到,next()方法可以恢复生成器状态并继续执行,其实send()是除next()外另一个恢复生成器的方法。

Python 2.5中,yield语句变成了yield表达式,也就是说yield可以有一个值,而这个值就是send()方法的参数,所以send(None)和next()是等效的。同样,next()和send()的返回值都是yield语句处的参数(yielded value)

关于send()方法需要注意的是:调用send传入非None值前,生成器必须处于挂起状态,否则将抛出异常。也就是说,第一次调用时,要使用next()语句或send(None),因为没有yield语句来接收这个值。close():

这个方法用于关闭生成器,对关闭的生成器后再次调用next或send将抛出StopIteration异常。

下面看看这两个方法的使用:a7f3086800b4e3a4444d9d743656ffa1.png

总结

本文介绍了Python迭代器和生成器的相关内容。通过实现迭代器协议对应的iter()和next()方法,可以自定义迭代器类型。对于可迭代对象,for语句可以通过iter()方法获取迭代器,并且通过next()方法获得容器的下一个元素。

像列表这种序列类型的对象,可迭代对象和迭代器对象是相互独立存在的,在迭代的过程中各个迭代器相互独立;但是,有的可迭代对象本身又是迭代器对象,那么迭代器就没法独立使用。

itertools模块提供了一系列迭代器,能够帮助用户轻松地使用排列、组合、笛卡尔积或其他组合结构。

生成器是一种特殊的迭代器,内部支持了生成器协议,不需要明确定义iter()和next()方法。

生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果。

如果你想更多的了解Python,点击以下视频跳转链接:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python哪些类型可以作为迭代器_Python教程|全面理解Python迭代器和生成器 的相关文章

  • SpringMvc

    简述 基于Java实现Mvc模型的轻量级web框架 配置案例过程 导入maven
  • 神经网络——非线性激活

    torch官网 torch nn PyTorch 1 11 0 documentation 非线性变换的主要目的就是给网中加入一些非线性特征 非线性越多才能训练出符合各种特征的模型 常见的非线性激活 ReLU 官网给出的例子 gt gt g
  • C语言求平均成绩小程序(以五个学科为例)

    include
  • 客户好评“收割机”,NPS高达0.7, 实在RPA6.8.0重磅升级解析

    近期 实在智能大模型新品 TARS RPA Agent 发布会召开 通过底层软件架构的全新优化和全面结合大语言模型实现 超进化 持续以AI技术为RPA行业提供领先的超自动化解决方案 同时在发布会上亮相的 还有备受关注的最新版RPA产品 实在
  • buuctf MD5

    打开是一串MD5密文 md5加密后是32位的字符 也有16位的 是去除32位的前后各八位所得 由字母和数字组成 字母要么全是大写要么全是小写 MD5加密是不可逆的加密 无法解密 但是可以爆破出来 给大家推荐一个可以爆破MD5加密的网站htt
  • 小码哥学习感想第一天

    开班须知 本小节知识点 了解 课堂纪律要求 了解 上课的时间和内容安排 了解 学习方法 了解 教学思想和目标 1 课堂纪律要求 手机静音 保持安静 很容易错过精彩 关键瞬间 低调听课 尊重他人 多点反馈 多点互动 积极思考 积极回答 大家一
  • pycharm内无法激活conda虚拟环境

    仅供参考 问题描述 在pycharm终端里conda activate xxx 没报错 但是并没有激活指定的xxx虚拟环境 解决方法 检查是否已将conda加入到系统环境变量内 查找了其他教程 说conda没有加入到环境变量内 但我的已经加
  • 签好软件定制开发合同,需要注意什么

    签订好一份责权分明 细节清晰的软件定制开发合同 对于任何软件定制开发合同的双方而言都是百利无害的 尤其对于软件开发软件定制开发合同这种非常容易引起争议的项目 签订合同的时候更是要慎之又慎 前期做好充足的准备 后期才能达到一个良好的效果 那么
  • Fastapi 学习笔记之请求多个参数

    1 混合使用 Path Query 和请求体参数 from fastapi import FastAPI Path from typing import Optional from pydantic import BaseModel app
  • 人工智能-目标识别:古典目标识别、R-CNN、SPP-NET、Fast-R-CNN、Faster-R-CNN、YOLO

    古典目标识别 第一部分 训练集构造 负样本 使用 select search ss 方法对区域进行融合 gt 计算每个候选区域域真实标记区域 GRadeonTruts GT 之间的重合 如果区域A与GT的重合度在20 50 之间 而且A与其
  • Android LCD(四):LCD驱动调试篇

    关键词 android LCD TFTSN75LVDS83B TTL LVDS LCD电压背光电压平台信息 内核 linux2 6 linux3 0系统 android android4 0 平台 samsung exynos 4210 e
  • Error:Execution failed for task ‘:app:mergeDebugResources‘. > Error: java.util.concurrent.ExecutionE

    我的解决办法是 点击Gradle Scripts下的build gradle Module app 添加如下两行 aaptOptions cruncherEnabled falseaaptOptions useNewCruncher fal
  • 计算机导论 复习 第一章 计算机学什么

    一 核心知识点 1 计算系统构成 硬件 系统软件 操作系统 应用程序 软件 2 算法的特征 算法的高级程序实现方法 3 程序设计语言 机器语言 汇编语言 高级语言 4 计算机发展简史 二 选择题 1 冯 诺伊曼体系结构是现代计算机基础 被人
  • 左程云 Java 笔记--前缀树 贪心算法

    文章目录 前缀树 贪心算法 例1 字典序排序 例3 哈夫曼编码 例四 堆的一个应用 N皇后 总结 前缀树 介绍前缀树 何为前缀树 如何生成前缀树 例子 一个字符串类型的数组arr1 另一个字符串类型的数组arr2 arr2中有哪些字符 是a
  • 【Java】使用Swing组件弹窗展示九十九乘法表

    目录 一 效果展示 二 完整代码 三 代码思路 一 效果展示 直接先上效果图 二 完整代码 import java awt import javax swing public class MultiplicationTable extend
  • 从零开始 React 服务器渲染

    一 前言 当我们选择使用 Node React 的技术栈开发 Web 时 React 提供了一种优雅的方式实现服务器渲染 使用 React 实现服务器渲染有以下好处 1 利于 SEO React 服务器渲染的方案使你的页面在一开始就有一个
  • 线段树的学习

    在力扣刷题中遇到一道 我的日程安排表 的题 经过求解和资料的参考利用线段树的方法解决 以下对线段树的知识进行一个简单的总结 线段树的定义 线段树是一种二叉搜索树 与区间树相似 它将一个区间划分成一些单元区间 每个单元区间对应线段树中的一个叶
  • 字符游戏-智能蛇的学习

    目标 实现可以智能化移动 不撞墙 自由追寻果实的贪吃蛇程序 即拥有感知 决策 行动的能力 学习过程 根据index中sin曲线的绘制过程可知我们可以知道可以用while循环反复打印的方式达到刷屏的效果 这样 我们将贪吃蛇移动的每一步都单独打
  • Nginx禁止访问某个目录或某个后缀文件

    1 Nginx禁止访问某个目录或某个后缀文件 1 禁止访问某些后缀文件 如php zip location php zip deny all 2 禁止访问某个目录下的某些后缀文件 location wp content uploads wp

随机推荐

  • 带参数的main函数

    为了说明带参数的main函数 我们首先来学习一下有关命令行的概念 命令行 在操作系统状态下 为执行某个程序而键入的一行字符称为命令行 命令行的一般形式为 命令名 参数1 参数2 参数3 参数n 参数之间以一个或多个空格隔开 例如 C gt
  • 面试3--智能指针

    面试题目3 智能指针有哪些 share 和unique有什么区别 如何实现一个unique 概念 智能指针是一个类 这个类的构造函数中传入一个普通指针 析构函数中释放传入的指针 智能指针的类都是栈上的对象 所以当函数 或程序 结束时会自动被
  • R小姐:mice 多重插补

    文章名称 mice Multivariate Imputation by Chained Equations in R 文章链接 https www jstatsoft org article view v045i03 加载mice包 li
  • SpringMVC学习(二)--前后端传值

    1 前端向后端传值 Controller public class TestController RequestMapping test 如果想要获得前台的参数 可直接定义 名字必须一样 public String test String
  • Spring Boot入门教程

    好的 下面是一份Spring Boot入门教程 希望能对您有所帮助 Spring Boot入门教程 1 什么是Spring Boot Spring Boot是一款用于构建独立的 生产级别的Spring应用程序的框架 它可以让我们更快地开发S
  • Jquery.Pagination分页插件的学习

    http blog csdn net xiaochengzi 2015 article details 51762432 编程小白 文章中出现的谬误希望大神指点 工作接到一个任务 需要把现在pagination的样式修改成前端给的样式 当时
  • WolframTones:用一种新科学谱写一种新音乐

    转载自 36氪人法地 地法天 天法道 道法自然 老子 道德经 即便你不信上帝 不信真主 不信佛陀 不信妈祖 总有种敬畏让你挥之不去 余音绕梁 总是让你情不自禁地发出赞美 2002年著名科学家发表了 一种新科学 一书 很快成为人类知识领域的一
  • Vue - 去掉路由中的#号

    vue router默认是hash模式 在hash模式下 是会有 号在URL上 可以在路由的第一行添加 mode history来去掉 号 const router new Router mode history routes 一开始用的t
  • nginx实践(一)、安装和部署

    很长一段时间没有更新blog 因为这一段时间 都在研究一个实时事件处理应用 计划把该实时事件处理服务 修改为分布式服务 相关内容以后再与大家汇报 好了 因为工作缘故 要分析一个使用nginx的应用 所以从本节开始 介绍一下nginx的相关实
  • H5页面在ios的浏览里返回不刷新页面,解决浏览器自带缓存的问题。

    1 利用pageshow来解决 pageshow的web api pageshow Web API 接口参考 MDN 2 解决 在app vue里面 isPageHide false 定义变量 created void window add
  • Connections between cities 【HDU - 2874】【在线LCA算法】

    题目链接 昨天刚学了在线LCA 今天就来硬刚这道题还是花了一整天的时间 不过对于LCA却有了更多的理解 这道题在讲述不同根的做法上尤其是很好的 题目告诉我们有N个节点和M条边 以及C次询问 每次查询的是 L R 这两个节点间的距离 还是算得
  • dbeaver 配置mysql数据库驱动

    右键点击要数据库连接选择 编辑连接 然后点击 编辑驱动设置 从mysql8版本后 mysql的驱动类名发生改变 变成了com mysql cj jdbc Driver 所以如果要连接的数据库版本在8之前 需将 设置 界面的 类名 处改为 c
  • 华为od机试 Python【快递装载】

    前言 本题使用python解答 如果需要Java版本 请参考 点我 题目 快递需要按照一定的规则装载 所有的快递放在长方体的盒子当中 我们的需要是尽可能装载更多的快递 并且不能让货车超载 需要计算最多能装多少个快递 快递数最多1000个 货
  • 双列集合系列之Map集合的初了解

    Welcome Huihui s Code World 接下来看看由辉辉所写的关于双列集合的相关操作吧 目录 Welcome Huihui s Code World 顶级接口Map 一 Map集合的特点 二 Map集合的常见子类 HashM
  • xss渗透(跨站脚本攻击)

    一 什么是XSS XSS全称是Cross Site Scripting即跨站脚本 当目标网站目标用户浏览器渲染HTML文档的过程中 出现了不被预期的脚本指令并执行时 XSS就发生了 这里我们主要注意四点 1 目标网站目标用户 2 浏览器 3
  • 项目管理中什么最重要?

    被问过多次这个问题 尤其是在面试的时候 有说需求最重要 有说控制最重要 有的冠冕堂皇 来个成本 质量 时间三要素 美其名曰都重要 免得以偏概全 经多方求证 思索 结合十余年的项目管理经历 敝以为 项目管理中干系人管理最重要 尤其是关键干系人
  • Java面向对象编程

    一个关系数据库文件中的各条记录 A 前后顺序不能任意颠倒 一定要按照输入的顺序排列 B 前后顺序可以任意颠倒 不影响库中的数据关系 C 前后顺序可以任意颠倒 但排列顺序不同 统计处理的结果就可能不同 D 前后顺序不能任意颠倒 一定要按照关键
  • textarea placeholder不显示

    textarea placeholder不显示 textarea 的 placeholder 属性值不显示的原因可能是
  • DirectD3D-纹理映射

    DirectD3D 纹理映射 标签 Direct3Ddirectx游戏游戏开发 2014 11 12 14 03 321人阅读 评论 0 收藏 举报 分类 DirectX 8 版权声明 本文为博主原创文章 未经博主允许不得转载 纹理映射的概
  • python哪些类型可以作为迭代器_Python教程|全面理解Python迭代器和生成器

    在Python中 很多对象都是可以通过for语句来直接遍历的 例如list string dict等等 这些对象都可以被称为可迭代对象 至于说哪些对象是可以被迭代访问的 就要了解一下迭代器相关的知识了 迭代器 迭代器对象要求支持迭代器协议的