Python中的迭代器:深入理解与实用指南

文章目录

    • 1. 迭代器的基本概念
    • 2. Python中的迭代器实例
    • 3. 自定义迭代器
      • 3.1 例子
      • 3.2 详细过程
    • 4. 迭代器的高级应用
    • 5. 常见问题与解答

迭代器是Python中非常核心的概念之一,在面试中也会被问到。下面我会详细介绍什么是迭代器,使用方法,以及使用自定义迭代器来优化代码。

1. 迭代器的基本概念

在Python中,迭代器是实现了迭代器协议的对象,即它们具备了__iter__()__next__()这两个方法。__iter__()方法返回迭代器对象本身,而__next__()方法则返回容器中的下一个元素。当容器中没有更多元素时,__next__()会抛出一个StopIteration异常来通知迭代终止。

示例图:

在这里插入图片描述

示例代码:

numbers = [1, 2, 3]
iter_obj = iter(numbers)  # 创建迭代器对象
print(next(iter_obj))  # 输出: 1
print(next(iter_obj))  # 输出: 2
print(next(iter_obj))  # 输出: 3
try:
    print(next(iter_obj))  # 超出范围,将抛出StopIteration异常
except StopIteration:
    print("迭代完成")

通过这个简单的例子可以看到迭代器如何在Python列表上工作,以及当所有元素被遍历完毕后如何正确地处理StopIteration异常。

2. Python中的迭代器实例

许多内置数据类型在Python中都支持迭代器,例如列表、元组、字典和集合等。此外,文件对象也是可迭代的,这使得读取文件变得极为便捷。

示例代码:

# 迭代字典
my_dict = {"apple": "red", "banana": "yellow", "cherry": "red"}
for key in my_dict:
    print(f"{key}: {my_dict[key]}")

# 文件迭代
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

例子说明:

  • 通过在字典my_dict上使用for循环,直接迭代访问了其所有键,并打印出相应的键值对。
  • 打开了一个文件,并使用for循环逐行读取,这里文件对象自身就是一个迭代器,它按需加载数据,非常适合读取大文件。

3. 自定义迭代器

创建自己的迭代器:这需要定义一个类并实现__iter__()__next__()方法。可以让对象支持迭代,提供更多的灵活性和功能。

3.1 例子

class CountDown:
    def __init__(self, start):
        self.current = start
    def __iter__(self):
        return self
    def __next__(self):
        if self.current > 0:
            num = self.current
            self.current -= 1
            return num
        raise StopIteration

# 使用自定义迭代器
counter = CountDown(3)
for num in counter:
    print(num)  # 输出: 3, 2, 1

这个自定义迭代器CountDown从一个指定的起始数开始向下倒数。每次调用__next__()方法时,它检查当前数是否大于0,如果是,则返回当前数并将其递减,直到达到0时抛出StopIteration异常,表明迭代结束。

3.2 详细过程

我觉得有必要分析一下这个代码的详细执行过程

当创建CountDown类的一个实例(counter = CountDown(3)),只有__init__方法被立即执行。__iter__方法是在迭代器被实际用于迭代时才调用,通常是在for循环或其他形式的迭代开始时。下面详细说明这个过程:

  1. 创建实例:当执行counter = CountDown(3)时:

    • __init__(self, start)方法被调用,其中selfCountDown的一个新实例,start是传入的参数3。

    • __init__方法内,实例的current属性被设置为3,初始化完成后,__init__方法结束。

  2. 开始迭代:当for num in counter:执行时:

    • 首先尝试获取counter对象的迭代器,这会自动调用counter.__iter__()方法。

    • CountDown类中,__iter__()方法定义为返回自身(return self),因此counter本身作为迭代器参与迭代过程。

    • 现在counter已经准备好按需返回值,等待for循环调用__next__()

  3. 迭代过程:for 循环调用counter.__next__()

    • 检查current的值是否大于0。

    • 如果大于0,返回current的当前值,并将current减1。

    • 如果current已经为0,__next__()方法抛出StopIteration异常,通知for循环迭代已结束。

现在对实例的创建和迭代过程应该很清晰了,__init__方法在实例创建时执行来设置初值,而__iter____next__则是在迭代实际发生时调用。__iter__返回迭代器(这里是实例自身),并且__next__用于在每次迭代中逐步递减计数,直到抛出StopIteration

4. 迭代器的高级应用

迭代器不仅可以用于简单的数据遍历,还可以用于更复杂的数据处理任务,如在数据流中实现映射和过滤操作。

示例代码:

# 使用迭代器实现一个简单的map-reduce
nums = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, nums)
total = sum(squared)
print(total)  # 输出: 55

上面使用了map()函数,它本身返回一个迭代器。map()应用了一个函数到nums列表的每个元素上,将每个元素平方。然后使用sum()函数直接求出所有平方数的总和。

5. 常见问题与解答

Q: 迭代器和生成器有什么区别? A: 生成器是一种特殊类型的迭代器,可以通过函数来实现,使用yield语句返回每次迭代的值。生成器通常用于更复杂或更大数据集的惰性处理。

Q: 为什么要使用迭代器? A: 迭代器提供了一种统一的方法来逐个访问集合中的元素,而不需要知道集合的内部结构。它们还有助于保持代码的可读性和内存效率,特别是处理大型数据集时。


参考:What are Iterators and Iterables in Python

推荐:

  • python 错误记录
  • python 笔记

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM之初识垃圾收集器

JDK 8:Parallel Scavenge(新生代) Parallel Old(老年代)JDK8以后:G1收集器 什么是串行回收和并行回收? Serial收集器:串行收集器 新生代使用标记复制算法,老年代使用标记…

JSON驱动的动态SQL查询:实现灵活条件筛选的查询

当我们构建动态 SQL 查询功能时,需要考虑到安全性和灵活性的平衡。本文将讨论如何通过 JSON 数据和 FreeMarker 模板构造动态 SQL 查询,以及如何减少 SQL 注入的风险。 JSON 数据与动态 SQL JSON 是一种常用的数据交换格式,它的灵活性和易读…

【读点论文】YOLOX: Exceeding YOLO Series in 2021,无锚框单阶段目标检测方案,解耦检测头的分类和回归分支,优化标签分配策略

YOLOX: Exceeding YOLO Series in 2021 Abstract 在本报告中,我们介绍了YOLO系列的一些经验改进,形成了一种新的高性能探测器—YOLOX。我们将YOLO检测器切换到无锚方式,并进行其他先进的检测技术,即去耦头和领先的标签分配策略S…

信号处理相关知识

一: 1.序列——三种典型序列通过matlab绘图即可 2.数字信号的自变量一定是整数,幅度上取值是有限的状态(不一定是整数)。 3.抽取和插值 4.模拟正弦信号sin(wt):w是角频率,单位rad/s,f是频率w/2Π。 5.假设用采样周…

浏览器工作原理与实践--浏览上下文组:如何计算Chrome中渲染进程的个数

经常有朋友问到如何计算Chrome中渲染进程个数的问题,那么今天就来完整地解答这个问题。 在前面“04 | 导航流程”这一讲中我们介绍过了,在默认情况下,如果打开一个标签页,那么浏览器会默认为其创建一个渲染进程。不过我们在“04 |…

Qt | 远程仓库

git | 基本操作 01 远程仓库 在了解之前,先注册github(gitee或者gitcode等等)账号,由于你的本地Git仓库和github仓库之间的传输是通过SSH加密的,所以需要一点设置: 第一步:创建SSH Key。在用户主目录下,看看…

姿态估计-人脸识别mesh-3d手势识别-3d目标检测-背景分割-人脸关键点

往期热门博客项目回顾:点击前往 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 AI健身教练-引体向上…

UE4 相机围绕某点旋转

关卡(一个相机CameraActor,一个Cube(名叫Target)): 关卡蓝图里的逻辑(为了大家看得清楚,特意连得很紧凑,也比较乱,不然一张截图放不下): 只对Yaw 只Pitch: 同样对Roll: 围绕任…

Modelsim与Verilog入门

0.什么是Modelsim? Modelsim是一个支持多语言的仿真环境,比如我知道的Verilog和VHDL语言都可以在里边使用,这俩都是硬件描述语言; 即就是个软件,你可以用Verilog语言来写代码,然后编译,仿真出…

C++学习进阶:异常

目录 1.异常处理机制 1.1.抛异常和捕获异常 1.1.1.异常机制的基本场景 1.1.2.函数调用中异常栈展开的匹配规则: 1.2.异常机制的实际应用场景 2.异常相关知识 2.1.异常安全和异常重新抛出 2.2.noexcept关键字 2.3.异常的优缺点 1.异常处理机制 我们在C语言…

Finding a needle in Haystack: Facebook’s photo storage——论文泛读

OSDI 2010 Paper 分布式元数据论文阅读笔记整理 问题 到2010年为止,用户已经在Facebook上传了超过650亿张照片,对于每个上传的照片,Facebook生成并存储四个不同大小的图像,导致目前存储了超过2600亿张图片,相当于超过…

AQS(AbstractQueuedSynchronizer)队列同步器源码解读

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 目录 1. 前言 2. AOS、AQS、AQLS的区别 3. AQS的底层原理 3.1. 核心思想 3.2. 数…

Qt 项目文件(.pro)概述

Qt 项目pro文件 引言一、pro文件初探二、部分参数详解 引言 Qt工程项目由项目文件(.pro)进行管理。qmake使用文件中的信息生成Makefile,其中包含构建每个项目所需的所有命令。pro文件通常包含源文件和头文件的列表、常规配置信息以及任何特定…

ST-GCN模型详解(+openpose)

ST-GCN模型详解(openpose) 一、什么是ST-GCN呢 基于骨架的动作识别(Skeleton-Based Action Recognition)主要任务是从一系列时间连续的骨骼关键点(2D/3D)中识别出正在执行的动作。因为牵涉到骨骼框架这种…

CentOS7升级openssl

文章目录 一 系统环境二 操作步骤三 版本检查 一 系统环境 公司服务器等保要求,修复openssl的高危漏洞。 本机使用centos7.9系统,openssl版本是1.0.2k,计划升级到1.1.1q 在执行下列操作前,务必要打快照做好备份,以防升…

030——从GUI->Client->Server->driver实现对红外遥控的控制

目录 1、 解决韦东山老师irda模块中断申请失败的bug 2、 client添加处理程序 3、 添加服务器处理程序和驱动处理句柄 4、 处理数据读出不准确问题 5、 修改后的展示 1、 解决韦东山老师irda模块中断申请失败的bug irda需要通过中断来触发读操作,申请中断需要引…

Octopus v2:斯坦福的嵌入设备专用大模型

斯坦福大学推出了 Octopus v2,这是一种突破性的设备上语言模型,旨在解决与现有模型相关的延迟、准确性和隐私问题。 NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑…

源码篇--Nacos服务--中章(1):Nacos服务端的启动

文章目录 前言一、Nacos Console 启动入口:二、启动过程:2.1 容器启动监听器:2.1.1 调整启动标识为正在启动状态:2.1.2 环境准备阶段:2.1.3 容器环境准备:2.1.4 自定义的环境变量 设置:2.1.5 服…

Spectre-v2 以及 Linux Retpoline技术简介

文章目录 前言一、Executive Summary1.1 Spectre-v2: Branch Predictor Poisoning1.2 Mitigating Spectre-v2 with Retpolines1.3 Retpoline Concept 二、BackgroundExploit Composition 三、(Un-)Directing Speculative Execution四、Construction (x86)4.1 Speculation Barri…

测试人员通常遇到的“坑”

网上看到一个帖子,从事多年的测试从业者,吐槽测试过程中遇到的“坑”,感觉比较有意思,我在工作当中也遇到通常的问题,看得出这位网友比较喜欢总结,帖子地址奉上,有兴趣的可以浏览一下&#xff1…