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

Python迭代器知多少

目录

目标

Python版本

官方文档

概述

自定义可迭代对象

自定义迭代器


目标

  1. 掌握迭代器的使用方法。
  2. 了解迭代器和可迭代对象的区别。
  3. 通过案例实现迭代器和可迭代对象。

Python版本

        Python 3.9.18


官方文档

迭代器https://docs.python.org/3.9/glossary.html#term-iterator


概述

迭代器

官方描述

An object representing a stream of data. Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its __next__() method just raise StopIteration again. Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container.

理解

  1. 迭代器必然实现了__iter__()__next__()方法。
  2. __iter__()返回迭代器对象,往往返回自己即self,该方法意味着它本身是可迭代的,可以用于for循环。
  3. __next__()返回容器中的下一个元素。当没有更多元素时仍然调用该方法则抛出 StopIteration 异常。后面的迭代器案例中会讲解如何通过next()方法优雅地遍历所有元素。

可迭代对象

官方描述

An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() method or with a __getitem__() method that implements Sequence semantics.

Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), …). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.

理解

  1. 只要实现了__iter__()或sequence语义的__getitem__()方法的对象就是可迭代对象。由此可见,迭代器必然是可迭代对象
  2. 可迭代对象是指一个能够一次返回一个成员的对象,所以常与for循环搭配使用。
  3. 常见的可迭代对象有:列表(list)、字典(dict)、元组(tuple)、字符串(str,每次迭代返回一个字符)、集合(set)、字典文件对象(每次迭代读取一行数据)。

自定义可迭代对象

需求

        创建班级类和学生信息类,一个班级包含多个学生,因此班级类提供添加学生的方法,并将学生信息循环打印。要求班级类是可迭代对象。

from collections.abc import Iterable, Iterator
class Student:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex=sex

class Classroom:
    def __init__(self, name):
        #班级名称
        self.name = name
        self.students = []
    def add(self,student):
        #添加学生对象
        self.students.append(student)
    def __iter__(self):
        return self

if __name__ == '__main__':
    student=Student("张三",24,"男")
    student2 = Student("李四", 25, "男")
    student3 = Student("王五", 26, "女")

    classroom=Classroom("123班")
    classroom.add(student)
    classroom.add(student2)
    classroom.add(student3)

    for student in classroom.students:
        print(student.name,student.age,student.sex)

    #判断classroom是不是迭代器(Iterator):False
    print(isinstance(classroom,Iterator))
    #判断classroom是不是可迭代对象(Iterable):True
    print(isinstance(classroom,Iterable))

    # 判断classroom是不是迭代器(Iterator):False
    print(isinstance(student, Iterator))
    # 判断classroom是不是可迭代对象(Iterable):False
    print(isinstance(student, Iterable))

结果

        班级类是可迭代对象,但不是迭代器,学生类不是可迭代对象也不是迭代器。这与类是否实现__iter__()方法有关。


自定义迭代器

需求

        创建班级类和学生信息类,一个班级包含多个学生,因此班级类提供添加学生的方法,并将学生信息循环打印。要求班级类是可迭代器。且使用next()方法优雅地遍历所有元素。

from collections.abc import Iterable, Iterator
class Student:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex=sex

class Classroom:
    def __init__(self, name):
        #班级名称
        self.name = name
        self.students = []
        #迭代器索引,从第一个索引开始。
        self.index=0
    def add(self,student):
        #添加学生对象
        self.students.append(student)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index<len(self.students):
            student = self.students[self.index]
            self.index+=1
            return student
        else:
            #如果没有下一个元素则抛出StopIteration异常
            raise StopIteration
if __name__ == '__main__':
    student=Student("张三",24,"男")
    student2 = Student("李四", 25, "男")
    student3 = Student("王五", 26, "女")

    classroom=Classroom("123班")
    classroom.add(student)
    classroom.add(student2)
    classroom.add(student3)

    #这里我用next()方法来遍历学生对象。
    iterator=iter(classroom)
    while True:
        #next()方法第二个参数作用:如果没有下一个元素了,则返回设定的默认值,这里我设定的默认值是None。
        student=next(iterator,None)
        if student :
            print(f"姓名: {student.name}, 年龄: {student.age}, 性别: {student.sex}")
        else:
            print("遍历完成。")
            break;

http://www.kler.cn/a/555532.html

相关文章:

  • 网络运维学习笔记 014网工初级(HCIA-Datacom与CCNA-EI)ACL访问控制列表
  • DeepSeek大模型下半场:开源、普惠与生态重构的技术革命
  • redis的缓存击穿,雪崩,穿透
  • git空文件夹不能提交问题
  • acm培训 part 7
  • VBA脚本将DeepSeek嵌入Word中教程
  • 【C++】实现一个JSON解析器
  • 【小游戏】C++控制台版本俄罗斯轮盘赌
  • JavaEE-SpringBoot快速入门
  • QT QLabel加载图片等比全屏自适应屏幕大小显示
  • 2025最新版Pycharm如何设置conda虚拟环境运行程序
  • 【Vue】前端记录点
  • LLM基础概念(RAG、微调流程、Prompt)
  • 利用ollama本地部署deepseek
  • AI大模型零基础学习(7):边缘智能与物联网——让AI走出云端
  • Go Web 开发基础:从入门到实战
  • 无人机避障——感知篇(采用Mid360复现Fast-lio)
  • 第四篇:开源生态与蒸馏模型的价值
  • leetcode day19 844+977
  • 【Java八股文】08-计算机网络面试篇