23. 迭代器

一、什么是迭代器

  迭代器 指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是重复。迭代器是用来迭代取值的工具,而涉及到把多个值循环取出的数据类型有:列表、字符串、元组、字典、集合、打开的文件对象等。

  我们可以通过 while 循环的方式取值,这种取值方式只适用于有索引的数据类型,如:列表、字符串、元组等。

names = ["Sakura","Mikoto","Shana"]i = 0
while i < len(names):print(names[i])i += 1

  为了解决基于索引迭代器取值的局限性,Python 需要提供一种能够不依赖索引的取值方式,这就是迭代器。在 Python 中,但凡是内置有 __iter__() 方法的对象都称为 可迭代对象。在 Python 中,列表、字符串、元组、字典、集合、打开的文件对象等都内置了 __iter__() 方法。调用可迭代对象的 __iter__() 方法会将其转换成迭代器对象。转换为迭代器对象后,我们可以通过 __next__() 方法获取迭代器对象的下一个值。

names = ["Sakura", "Mikoto", "Shana"]iterator = person.__iter__()
print(iterator)
print(type(iterator), end="\n\n")while True:try:print(iterator.__next__())except StopIteration:break
names = ["Sakura", "Mikoto", "Shana"]iterator = iter(names)
print(iterator)
print(type(iterator), end="\n\n")while True:try:print(next(iterator))except StopIteration:break

如果我们迭代到最后一项,再调用 __next__() 方法或 next() 方法会抛出 StopIteration 异常;

  迭代器对象 是指内置有 __next__() 方法和 __iter__() 方法的对象。调用迭代器对象的 __next__() 方法将得到迭代器对象的下一个值。调用迭代器对象的 __iter__() 方法将得到迭代器的本身,与没调用该方法一样。

person = {"name":"Sakura","age":10}iterator = iter(person)
print(iterator is  iterator.__iter__() is iterator.__iter__().__iter__())

  如果我们想判断某一个数据类型或对象是否可以迭代,我们可以使用 collections 模块来判断;

from collections.abc import Iterable, Iteratordata = "Sakura"
print("可迭代对象-字符串:", isinstance(data, Iterable))
print("迭代器-字符串:", isinstance(data, Iterator))
print()data = ["Sakukra", "Mikoto", "Shana"]
print("可迭代对象-列表:", isinstance(data, Iterable))
print("迭代器-列表:", isinstance(data, Iterator))
print()data = ("Sakukra", "Mikoto", "Shana")
print("可迭代对象-元组:", isinstance(data, Iterable))
print("迭代器-元组:", isinstance(data, Iterator))
print()data = {"Sakukra", "Mikoto", "Shana"}
print("可迭代对象-集合:", isinstance(data, Iterable))
print("迭代器-集合:", isinstance(data, Iterator))
print()data = {"name": "Sakura", "age": 10}
print("可迭代对象-字典:", isinstance(data, Iterable))
print("迭代器-字典:", isinstance(data, Iterator))
print()
from collections.abc import Iterable, Iteratorclass People:def __init__(self):self.container = []people = People()
print("可迭代对象:", isinstance(people, Iterable))
print("迭代器:", isinstance(people, Iterator))

二、自定义迭代器

  只要在类中定义 __iter__() 方法,那么这个类创建出来的对象一定是可迭代的。通俗的说:一个具备了 __iter__() 方法的对象,就是一个可迭代对象。

from collections.abc import Iterable, Iteratorclass People:def __init__(self):self.container = []def __iter__(self):passpeople = People()
print(isinstance(people, Iterable))
print("迭代器:", isinstance(people, Iterator))

  如果想实现自定义迭代器的话,除了在类中定义 __iter__() 方法还需要在类中再定义 __next__() 方法,即一个实现了 __iter__() 方法和 __next__() 方法的对象,就是迭代器。

from collections.abc import Iterable, Iteratorclass People:def __init__(self):self.container = []def add(self, name):self.container.append(name)def __iter__(self):# 这个方法有两个功能:# 1.标记用当前类创建出来的对象是一定是可迭代对下个你# 2.当调用iter()函数时,这个方法会被自动调用,返回的自己指定的那个迭代器return MyIterator(self)class MyIterator:def __init__(self, obj):self.obj = objself.current = 0def __iter__(self):passdef __next__(self):# 这个方法有两个功能:# 1.标记当前类创建的对象(一定有__iter__()方法)一定是迭代器# 2.当调用next()函数时,这个方法会自动调用,它返回一个数据if self.current < len(self.obj.container):item = self.obj.container[self.current]self.current += 1return itemelse:raise StopIterationpeople = People()
print("People-可迭代对象:", isinstance(people, Iterable))
print("People-迭代器:", isinstance(people, Iterator))
print()iterator = MyIterator(people)
print("MyIterator-可迭代对象:", isinstance(iterator, Iterable))
print("MyIterator-迭代器:", isinstance(iterator, Iterator))
print()people.add("Sakura")
people.add("Mikoto")
people.add("Shana")for item in people:print(item)

 for 循环是一个已经实现的功能,它里面自带了 iter()、next() 方法,并且带有 StopIteration 异常判断,通过这个异常判断来决定是否还需要获取迭代器对象。如果自己规定用 None 来表示数据获取完毕,但是 for 循环的代码依然用的是异常处理,所以 for 循环会产生死循环。

from collections.abc import Iterable, Iteratorclass People:def __init__(self):self.container = []self.current = 0def add(self, name):self.container.append(name)def __iter__(self):# 这个方法有两个功能:# 1.标记用当前类创建出来的对象是一定是可迭代对下个你# 2.当调用iter()函数时,这个方法会被自动调用,返回的自己指定的那个迭代器return selfdef __next__(self):# 这个方法有两个功能:# 1.标记当前类创建的对象(一定有__iter__()方法)一定是迭代器# 2.当调用next()函数时,这个方法会自动调用,它返回一个数据if self.current < len(self.container):item = self.container[self.current]self.current += 1return itemelse:self.current = 0raise StopIterationpeople = People()people.add("Sakura")
people.add("Mikoto")
people.add("Shana")for item in people:

当对一个可迭代对象调用 iter() 方法时,它会自动调用这个可迭代对象的 __iter__() 方法,这个方法返回的对象当做迭代器;

当对一个迭代器对象i调用 next() 方法时,它会自动调用这个迭代器对象的 __next__() 方法,这个方法返回想要的那个数据;

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

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

相关文章

mybatisplus 分库查询

mybatisplus 分库查询 比如我们的项目有两个数据库 不同的表在不同的库 我们是可以使用mybatisplus来实现 首选引入pom <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><vers…

UE材质常用节点

Desaturation 去色 饱和度控制 Panner 贴图流动 快捷键P Append 附加 合并 TexCoord UV平铺大小 快捷键U CustomRotator 旋转贴图 Power 幂 色阶 Mask 遮罩 Lerp 线性插值 快捷键L Abs 绝对值 Sin / Cos 正弦/余弦 Saturate 约束在0-1之间 Add 相加 快捷键A Subtra…

深入了解IPv6——光猫相关设定:DNS来源、DHCPv6服务、前缀来源等

光猫IPv6设置后的效果对比图&#xff1a; 修改前&#xff1a; 修改后&#xff1a; 一、DNS来源 1. 网络连接 来源&#xff1a; 从上游网络&#xff08;如运营商&#xff09;获取 IPv6 DNS 信息&#xff0c;通过 PPPoE 或 DHCPv6 下发。 特点&#xff1a; DNS 服务器地址直…

CentOS7下,hive4.0.0安装部署

hive安装部署 为了简单起见&#xff0c;都安装到node1服务器上。&#xff08;集群&#xff1a;node1&#xff0c;node2&#xff0c;node3&#xff09; 环境&#xff08;已安装&#xff09;&#xff1a;Hadoop3.4.0&#xff0c;jdk-8u171 需要安装&#xff1a;MySQL8.4.3&…

简单记录一下 Debian12 安装 FusionPBX 要点

cd /usr/src git clone https://github.com/fusionpbx/fusionpbx-install.sh.git 编辑 fusionpbx-install.sh/debian/resources/config.sh 下面的配置可以根据需要进行修改 domain_nameip_address # hostname, ip_address or a custom valuesystem_us…

[ZMQ] -- ZMQ通信收发多个Proto数据结构 2

为了在 ZeroMQ 的一帧数据中发送两个不同的主题&#xff08;topic&#xff09;&#xff0c;并且每个主题包含不同的 Protobuf 消息&#xff0c;可以使用多部分消息的功能。具体来说&#xff0c;将发送一个包含四部分的消息&#xff1a; 第一个主题&#xff08;topic1&#xff…

LLMs之Llama-3:Llama-3.3的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama-3&#xff1a;Llama-3.3的简介、安装和使用方法、案例应用之详细攻略 目录 相关文章 LLMs之LLaMA&#xff1a;LLaMA的简介、安装和使用方法、案例应用之详细攻略 LLMs之LLaMA-2&#xff1a;LLaMA 2的简介(技术细节)、安装、使用方法(开源-免费用于研究和商业用途…

burp(2)利用java安装burpsuite

BurpSuite安装 burpsuite 2024.10专业版&#xff0c;已经内置java环境&#xff0c;可以直接使用&#xff0c; 支持Windows linux macOS&#xff01;&#xff01;&#xff01; 内置jre环境&#xff0c;无需安装java即可使用&#xff01;&#xff01;&#xff01; bp2024.10下载…

攻防世界逆向刷题笔记(新手模式6-?)

6.1000clicks 看题目名字似乎是让咱们点击1000次之后才会出flag。本来打算用CE看能不能搜索出来数值&#xff0c;技术不到家&#xff0c;最后没有搜索到&#xff0c;还导致永劫无间打不了了。所以还是拿出IDA老实分析。 直接搜索flag字符&#xff0c;出来一大堆。张紫涵大佬说…

Coding Caprice - dynamic programming10

300. 最长递增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {int len nums.size();map<int, int> record;int out(1);for(int &i: nums){int max_len 0;for(auto &[x, y]: record){if(x<i){max_len max(max_len, record…

文本编辑器与正则表达式

1. VIM 编辑器 1.1 VIM 基本概念 VIM 是一个高度可定制的文本编辑器&#xff0c;广泛用于程序员的日常开发中。与传统的文本编辑器不同&#xff0c;VIM 基于模式操作&#xff0c;具有以下几个主要特点&#xff1a; 普通模式&#xff1a;用于浏览和修改文本。插入模式&#x…

lc146LRU缓存——模仿LinkedHashMap

146. LRU 缓存 - 力扣&#xff08;LeetCode&#xff09; 法1&#xff1a; 调用java现有的LinkedHashMap的方法&#xff0c;但不太理解反正都不需要扩容&#xff0c;super(capacity, 1F, true);不行吗&#xff0c;干嘛还弄个装载因子0.75还中途扩容一次浪费时间。 class LRUC…

Tomcat(76)如何在Tomcat中配置集群会话状态同步?

在Tomcat中配置集群会话状态同步是确保应用程序高可用性和冗余的重要步骤。以下是详细的配置步骤和代码示例&#xff0c;以确保在Tomcat集群中实现会话状态同步。 1. 配置Tomcat Cluster 首先&#xff0c;需要修改Tomcat的server.xml文件来配置集群和会话复制。 a. 编辑 ser…

CentOS 上如何查看 SSH 服务使用的端口号?

我们知道&#xff0c;linux操作系统中的SSH默认情况下&#xff0c;端口是使用22&#xff0c;但是有些线上服务器并不是使用的默认端口&#xff0c;那么这个时候&#xff0c;我们应该如何快速知道SSH使用的哪个端口呢&#xff1f; 1、通过配置文件查看 cat /etc/ssh/sshd_confi…

IoTDB Allocate WAL Buffer Fail Because out of memory

问题及现象 时序数据库 IoTDB 集群报错&#xff1a; The write is rejected because the wal directory size has reached the threshold 53687091200 bytes. You may need to adjust the flush policy of the storage storageengine or the IoTConsensus synchronization pa…

定时/延时任务-Kafka时间轮源码分析

文章目录 1. 概要2. TimingWheel2.1 核心参数2.2 添加任务2.3 推进时间 3. TimerTaskList3.1 添加节点3.2 删除节点3.3 刷新链表3.4 队列相关 4. 时间轮链表节点-TimerTaskEntry5. TimerTask6. Timer 和 SystemTimer - 设计降级逻辑7. 上层调用8. 小结 1. 概要 时间轮的文章&a…

厦门凯酷全科技有限公司深耕抖音电商运营

在数字经济飞速发展的今天&#xff0c;抖音电商平台以其独特的社交属性和庞大的用户基础&#xff0c;迅速成为众多品牌和商家的新战场。在这个充满机遇与挑战的市场中&#xff0c;厦门凯酷全科技有限公司凭借其专业的服务、创新的理念和卓越的执行力&#xff0c;成为了抖音电商…

探秘多AI Agent模式:机遇、应用与未来展望(5/30)

摘要&#xff1a;多 AI Agent 模式是一种强大的人工智能架构&#xff0c;它利用多个智能体&#xff08;Agent&#xff09;之间的协作与交互来解决复杂问题、执行多样化任务并模拟复杂系统行为。在这种模式中&#xff0c;每个 Agent 都具备独立的感知、决策和行动能力&#xff0…

java之集合(详细-Map,Set,List)

1集合体系概述 1.1集合的概念 集合是一种容器&#xff0c;用来装数据的&#xff0c;类似于数组&#xff0c;但集合的大小可变&#xff0c;开发中也非常常用。 1.2集合分类 集合分为单列集合和多列集合 Collection代表单列集合&#xff0c;每个元素&#xff08;数据&#xff…

UDS自动化测试-Service 0x27(CAPL调用dll实现key计算)

文章目录 关联文章一、CANoe加载诊断数据库cdd、dll文件二、CAPLdiagGenerateKeyFromSeed关联文章 UDS - 深论Security Access Service 27服务-安全访问状态转换 CDD文件——CANdelaStudio Vector——CAPL语言设计 CANoe诊断测试 相信读者基于Diagnostic/ISO TP Confighratio…