首页 > 编程语言 >Python小白学习教程从入门到入坑------第三十一课 迭代器(语法进阶)

Python小白学习教程从入门到入坑------第三十一课 迭代器(语法进阶)

时间:2024-11-15 11:50:08浏览次数:3  
标签:__ 迭代 Python print iter next 对象 到入 ------

目录

一、可迭代对象Iterable

1.1 可迭代对象的条件

1.2 for 循环工作原理

1.3 isinstance()

二、迭代器  Iterator

2.1 __iter__() 和 __next__()

2.2 可迭代对象&迭代器

2.2.1 定义与特性

2.2.2 关系与转换

2.2.3 应用场景

三、迭代器协议(了解即可)

四、自定义迭代器类



在这一节,我将向大家介绍Python中的迭代器和生成器,在介绍之前我们先回顾一下什么是可迭代对象?

一、可迭代对象Iterable

含义: 可以通过for ..in….这类语句遍历读取数据的对象称之为可迭代对象

遍历(迭代):依次从对象中把一个个元素取出来的过程

可迭代对象的数据类型:str、list、tuple、dict、set 等

1.1 可迭代对象的条件

(满足了这两个条件也可以称为可迭代对象):

1、对象实现了__iter__()方法

2、__iter__() 方法返回了迭代器对象

1.2 for 循环工作原理

1、先通过__iter__() 获取可迭代对象的迭代器

2、对获取到的迭代器不断调用__next__() 方法来获取下一个值并将其赋值给临时变量 i

1.3 isinstance()

判断一个对象是否是可迭代对象或者是一个己知的数据类型

导入模块:

from collections.abc import Iterable   # 导入模块

isinstance(o,t)     o:对象,t:类型,可以是直接或者间接类名、基本类型或者元组

eg:

from collections.abc import Iterable   # 导入模块

# 示例对象
my_list = [1, 2, 3]
my_str = "hello"
my_int = 42

# 判断是否是可迭代对象
print(isinstance(my_list, Iterable))  # 输出: True
print(isinstance(my_str, Iterable))  # 输出: True
print(isinstance(my_int, Iterable))  # 输出: False

在这个例子中,my_list 是一个列表,my_str 是一个字符串,它们都是可迭代对象,因此 isinstance() 返回 True。而 my_int 是一个整数,不是可迭代对象,所以 isinstance() 返回 False。

此外,还可以使用 isinstance() 来判断一个对象是否是某个具体的数据类型,比如列表、元组、字典等:

# 判断是否是列表
print(isinstance(my_list, list))  # 输出: True

# 判断是否是元组
my_tuple = (1, 2, 3)
print(isinstance(my_tuple, tuple))  # 输出: True

# 判断是否是字典
my_dict = {'a': 1, 'b': 2}
print(isinstance(my_dict, dict))  # 输出: True

二、迭代器  Iterator

含义:迭代器是一个可以记住遍历位置的对象,迭代器对象从集合的第一个元素开始访
问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

2.1 __iter__() 和 __next__()

迭代器有两个基本的方法:__iter__() 和 __next__()

__iter__() 方法:返回迭代器对象本身

__next__() 方法:返回容器的下一个元素,并将其移动到下一个位置,如果容器中没有更多的元素,则返回一个StopIteration异常

步骤:

1、iter() 调用对象的__iter__(),并把__iter__() 方法的返回结果作为自己的返回值

2、next() 调用对象的__next__(),一个个取出元素

3、所以元素都取完了,__next__()将引发StopIteration异常

接下来通过一个例子来更好的了解这两个方法:

# 第一种方法:
li = [1,2,3,4]
# 1.创建迭代器对象
li2 = iter(li)
print(li2)

# 2.获取下一条数据
print(next(li2))   # 1
print(next(li2))   # 2
print(next(li2))   # 3
print(next(li2))   # 4

# 3.取完元素后,再使用next()会引发StopIteration异常
print(next(li2))   # StopIteration异常

# 第二种方法:
li = [1,2,3,4]
# 1.创建迭代器对象
li2 = li.__iter__()
print("li2:",li2)

# 2.获取下一条数据
print(li2.__next__())   # 1
print(li2.__next__())   # 2
print(li2.__next__())   # 3
print(li2.__next__())   # 4

# 3.取完元素后,再使用next()会引发StopIteration异常
print(li2.__next__())   # StopIteration异常

2.2 可迭代对象&迭代器

凡是可以作用于for循环的都属于可迭代对象
凡是可以作用于next()的都是迭代器

2.2.1 定义与特性

可迭代对象(Iterable)

定义:可迭代对象是指实现了iter()方法的对象,该方法返回一个迭代器对象,允许对象被遍历

特性:

1、可以使用for循环进行遍历

2、常见的可迭代对象包括列表(list)、元组(tuple)、集合(set)、字典(dict)、字符串(str)等

3、在迭代过程中,不会记忆之前的访问状态,每次都从头开始遍历

迭代器(Iterator)

定义:迭代器是指实现了iter()和next()方法的对象。其中,iter()方法返回迭代器对象本身(这通常是一个已经实现了迭代协议的对象,因此调用此方法通常只是简单地返回对象自身),而next()方法用于返回迭代器的下一个元素

特性:

1、可以通过next()函数获取下一个元素,直到遍历完所有元素时抛出StopIteration异常

2、迭代器只能单向遍历,不能反向遍历

3、在迭代过程中,会记忆之前的访问状态,每次调用next()方法时,会从上一次停止的位置开始遍历

4、迭代器实现了惰性计算,即只在需要时才生成下一个值,这使得它在处理大数据集时非常高效

2.2.2 关系与转换

关系:如果一个对象是迭代器,那么它一定是可迭代的。但反过来,如果一个对象是可迭代的,它不一定是迭代器。

转换:可以使用 iter() 函数将可迭代对象转换为迭代器。例如,iter([])会将一个空列表转换为一个迭代器对象。

我们如何判断一个对象时可迭代对象还是迭代器对象呢?

根据1.3可得需要用到 isinstance 来判别

eg:

from collections.abc import Iterable,Iterator  # 第一步导入模块
name = "junjun"   # 定义对象
print(isinstance(name,Iterable))  # 判断对象是否为可迭代对象,True,说明为可迭代对象
print(isinstance(name,Iterator))  # 判断对象是否为迭代器对象,False,说明不是迭代器对象

可得到一个结论:可迭代对象并不一定是迭代器对象 

但是可以通过iter()将可迭代对象转换为迭代器

eg:

from collections.abc import Iterable,Iterator  # 第一步导入模块
name = "junjun"   # 定义对象
print(isinstance(name,Iterable))  # 判断对象是否为可迭代对象,True,说明为可迭代对象
print(isinstance(name,Iterator))  # 判断对象是否为迭代器对象,False,说明不是迭代器对象
name2 = iter(name)  # 将name转换成迭代器对象
print(isinstance(name2,Iterable))  # 判断对象是否为可迭代对象,True,说明为可迭代对象
print(isinstance(name2,Iterator))  # 判断对象是否为迭代器对象,True,说明是迭代器对象

可以得到另一个结论:迭代器对象一定是可迭代对象 

总结:
1、可迭代对象可以通过iter()转换成迭代器对象
2、如果一个对象拥有__iter__(),是可迭代对象,如果一个对象拥有__next__()和__iter__()方法,是迭代器对象

2.2.3 应用场景

可迭代对象:适用于需要被遍历但不需要惰性计算的场景

例如,当需要遍历一个列表中的所有元素时,可以直接使用for循环

迭代器:适用于需要惰性计算或需要自定义遍历方式的场景

例如,当需要遍历一个非常大的数据集时,使用迭代器可以避免一次性将所有数据加载到内存中。此外,迭代器还可以用于实现自定义的遍历逻辑,如逆序遍历或按特定步长遍历

三、迭代器协议(了解即可)

在Python中,迭代器协议是指一种用于定义可迭代对象(iterable)和迭代器(iterator)的协议它提供了一种标准的方法来使对象可迭代,并能够在循环中逐一访问元素

迭代器协议主要涉及两个方法:__iter__() 和 __next__()

1、__iter__() 方法:

① 对于迭代器对象来说,通常这个方法会返回迭代器对象本身,使得迭代器也可以作为可迭代对象使用。这意味着迭代器需要实现这个方法,但返回的值通常是 self

② 对于可迭代对象(如列表、元组等),__iter__() 方法的作用是返回一个迭代器对象,该对象用于遍历可迭代对象中的元素

2、__next__() 方法:

① 这个方法应该返回序列中的下一个元素

② 当没有更多的元素可以返回时,应该引发一个 StopIteration 异常,以通知迭代过程已经结束。

一个对象如果实现了这两个方法(或对于迭代器来说,主要是实现了 __next__() 方法,并且可能也实现了返回自身的 __iter__() 方法),那么它就被认为是一个迭代器

迭代器的好处包括:

1、节省内存:迭代器只保存当前迭代的元素和迭代状态,而不是保存整个容器的数据

2、支持惰性求值:迭代器只有在需要时才会计算下一个元素,可以在处理大量数据时减少计算量

3、支持无限序列:迭代器可以处理无限序列,因为它只需要在需要时生成下一个元素

4、简化代码:使用迭代器可以减少代码的复杂度,提高代码的可读性和可维护性

在Python中,很多内置类型和自定义对象都是可迭代的,并且可以通过调用 iter() 函数获取对应的迭代器。此外,生成器也是迭代器的一种特殊实现,它通过函数来实现迭代逻辑,并使用 yield 语句来产生值。

四、自定义迭代器类

在Python中,自定义迭代器类通常是通过实现迭代器协议来完成的

迭代器协议要求一个对象必须实现两个特殊方法:__iter__() 和 __next__()

然而,对于纯粹的迭代器对象来说,__iter__() 方法通常只是简单地返回对象自身,而真正的迭代逻辑则是由 __next__() 方法来实现的

先通过一个普通的类带大家回忆一下,类的相关知识

eg1:普通的类

class Test(object):        # 定义了一个名为 Test 的类
    # 初始值是1,逐步递增1
    def __init__(self):   # Test 类有一个初始化方法 __init__,设置了一个实例变量 num,初始值为 1
        self.num = 1
    def funa(self):       # Test 类还有一个方法 funa,打印当前的 num 值,并将 num 增加 1
        print(self.num)
        self.num += 1
te = Test()                # 创建了一个实例 te
# 用for循环取出
for i in range(5):
    te.funa()

输出内容:

1
2
3
4
5

eg2:下面是一个自定义迭代器类的例子,这个类会生成一个指定范围内的整数序列:

class MyRangeIterator:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.current = start - 1  # 初始化时current设为start的前一个值,以便第一次调用__next__()时返回start

    def __iter__(self):
        return self  # 返回迭代器对象本身

    def __next__(self):
        if self.current < self.end:
            self.current += 1  # 更新当前值
            return self.current  # 返回当前值
        else:
            raise StopIteration  # 如果没有更多元素,则抛出StopIteration异常

# 使用自定义迭代器
iterator = MyRangeIterator(1, 5)
for num in iterator:
    print(num)  # 输出: 1 2 3 4

今天的分享就到这里了,希望能对大家有所帮助~

标签:__,迭代,Python,print,iter,next,对象,到入,------
From: https://blog.csdn.net/qq_64441210/article/details/143761182

相关文章

  • 基于springboot+vue实现的人事管理系统 (源码+L文+ppt)4-084
      摘 要人事管理系统是企业用以维护员工信息、管理人力资源活动和优化组织效能的关键工具。该系统具备多项功能,包括员工信息管理、部门协调、培训安排、职位调整、考勤追踪、请假审批、奖惩记录、工资发放以及员工积分管理等。管理员端提供全面控制,允许系统管理员执行从......
  • node.js毕设网上投稿管理系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于毕设网上投稿管理系统的研究,现有研究主要以传统的投稿管理模式为主,专门针对毕设网上投稿管理这一特定情境的研究较少。目前的投稿管理多集中于一般......
  • 低轨增强”将为世界卫星导航发展带来新赋能!
    来源:北斗网 发布时间:2020-01-22近年来,随着美国GPS、俄罗斯GLONASS、中国北斗卫星导航系统和欧洲Galileo等四大卫星导航系统提供全球服务,世界卫星导航步入新时代。各主要卫星导航国家瞄准更高服务精度、更加多样功能、更加可靠服务,正在着手开展新一代系统建设和新一轮竞技。......
  • node.js毕设师生科研信息管理系统(程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于毕设师生科研信息管理系统的研究,现有研究主要以教师科研信息管理、学生科研信息管理等独立模块为主,专门针对毕设师生科研信息一体化管理的研究较少......
  • Java 常用加密解密算法
    Java常用加密解密算法 概要  加密算法是一种用数学方法对数据进行变换的技术,目的是保护数据的安全,防止被未经授权的人读取或修改。加密算法可以分为三大类:对称加密算法、非对称加密算法和哈希算法(也叫摘要算法)。  本文来梳理下开发中常用到的数据编码中的Base64以及常......
  • 京东 2025届秋招 自然语言处理
    文章目录个人情况一面/HR面10min二面/技术面1h三面/技术面1h四面/线下HR面20min个人情况先说一下个人情况:学校情况:211本中9硕,本硕学校都一般,本硕都是计算机科班,但研究方向并不是NLP,而是图表示学习论文情况:1A(NeurIPS)+1B(ICDM)已录用,还有一篇A会(AAAI2025)最近......
  • thinkphp 6.0.* 升级到thinkphp 6.0.15最新版的方法
    ​虽然thinkphp官方目前更新到了8.x版本,但是旧项目是使用thinkphp6.0.*,如果直接升级到thinkphp6.1.*或者8.*,项目会运行错误,那么应该怎么升级到thinkphp6.0.*的最新版呢?方法是:打开项目根目录下的composer.json文件,找到下面的代码"require":{"php":">=7.2.5",......
  • 百度 2025届秋招提前批 文心一言大模型算法工程师
    文章目录个人情况一面/技术面1h二面/技术面1h三面/技术面40min个人情况先说一下个人情况:学校情况:211本中9硕,本硕学校都一般,本硕都是计算机科班,但研究方向并不是NLP,而是图表示学习论文情况:1A(NeurIPS)+1B(ICDM)已录用,还有一篇A会(AAAI2025)最近快出结果了,以及一......
  • Docker && Kubernetes
     Docker镜像与容器Docker中有两个重要概念。一个是容器(Container):容器特别像一个虚拟机,容器中运行着一个完整的操作系统。可以在容器中装Nodejs,可以执行npminstall,可以做一切你当前操作系统能做的事情另一个是镜像(Image):镜像是一个文件,它是用来创建容器的。如果你有装过......
  • PHP实现两张图片的合并
    要求首先要确认GD库是否安装,若未安装则需要去先安装GD库后再进行操作有两个方法可快速检查是否安装GD库:1、在PHP脚本中用 phpinfo() 来查看配置信息2、在命令行中执行php-m命令来查看是否有此模块效果这里做了个简单的页面方便看合并的效果代码页面代码如下<!DO......