Python 中的 Iterable 和 Iterator(Iterable and Iterator in Python)

Python 中的 Iterable 和 Iterator(Iterable and Iterator in Python)

文章目录

  • Python 中的 Iterable 和 Iterator(Iterable and Iterator in Python)
    • Introduction 导言
    • Iterable VS Iterator
    • 为什么 Python 有这种特殊的设计special design?
    • 如何获取迭代器Iterator?
      • 1. 使用 iter() 函数
      • 2. 实现 `__iter__()` and `__next__()` 方法
      • 3. 使用生成器Generator
    • Python 中的 for 循环究竟是如何工作的?
    • Conclusion 结论

Introduction 导言

Iterable 和 Iterator 是 Python 的重要概念。然而,有时可能会让人感到困惑。本篇文章将深入探讨这些概念,帮助您完全理解它们。

Iterable VS Iterator

首先,我们应该知道 可迭代的对象Iterable 和 迭代器Iterator 是不同的。确切地说,Iterator 是 Iterable 的子类。一个 Iterable 对象,如 list , tuple , dict , setstr ,可以通过 iter() 函数产生一个 Iterator。例如

my_list = [1, 2, 3, 4, 5]
print(type(my_list))
# <class 'list'>

my_list_iterator = iter(my_list)
print(type(my_list_iterator))
# <class 'list_iterator'>

直观地说,任何可以通过 for...in... 循环迭代的对象都是 Iterable 对象。Iterator 也是 Iterable,因为它是 Iterable 的子类。我们可以使用 isinstance() 函数来检查它:

from collections.abc import Iterable, Iterator
my_list = [1, 2, 3, 4, 5]
my_list_iterator = iter(my_list)

isinstance(my_list,Iterable)
#True
isinstance(my_list,Iterator)
#False
isinstance(my_list_iterator,Iterable)
#True
isinstance(my_list_iterator,Iterator)
#True

让我们来看看 Python 3.9 _collections_abc.py 源代码:

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            return _check_methods(C, "__iter__")
        return NotImplemented

    __class_getitem__ = classmethod(GenericAlias)


class Iterator(Iterable):

    __slots__ = ()

    @abstractmethod
    def __next__(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration

    def __iter__(self):
        return self

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            return _check_methods(C, '__iter__', '__next__')
        return NotImplemented

很明显,Iterator 继承自 Iterable。

Iterator 和 Iterable 的区别在于:

  • 可迭代对象Iterable 可以一次性打印所有元素。它确实包含了所有元素。
  • 迭代器Iterator 就像一个 “工厂factory”,它保存了生成元素elements的方法,而我们只能使用 next() 函数逐个生成元素elements。我们不能一次打印所有元素elements,因为迭代器Iterator只知道如何生成元素的方法,而不会真正包含任何元素。
my_list = [1, 2, 3, 4, 5]
print(my_list)
# [1, 2, 3, 4, 5]

my_list_iterator = iter(my_list)
print(my_list_iterator)
# <list_iterator object at 0x7f048a4b67f0>

next(my_list_iterator)
# 1
next(my_list_iterator)
# 2
next(my_list_iterator)
# 3
next(my_list)
# TypeError: 'list' object is not an iterator

为什么 Python 有这种特殊的设计special design?

因为在 Python 中,操作一个大型容器large container(list/set/dict 等)往往非常耗时且效率低下。有时我们并不需要一次使用所有元素all the elements at once,我们只需要一次使用一个元素use one element at a time。因此,保存一个方法并在需要时产生一个元素saving a method and produce an element when we need one,而不是保存所有元素rather than saving all elements,是一个很好的主意。这样既能减少时间成本,又能减少空间成本。

简而言之,Python 中的 Iterable 对象是一个可以被遍历(通过 for 循环)的对象。Iterator 是 Iterable 的子类,但它包含一个产生项item的方法而不是项items本身。

如何获取迭代器Iterator?

1. 使用 iter() 函数

正如前面的示例所示,通过 iter() 将 Iterable 转换为 Iterator 非常方便。

2. 实现 __iter__() and __next__() 方法

迭代器Iterator对象必须实现两个特殊方法: __iter__()__next__() 。我们可以自己定义这两个方法,使对象object成为一个迭代器Iterator。

__iter__() 是迭代器Iterator初始化initialization时调用的方法method。它应该返回一个具有 __next__() 方法的对象object。换句话说,它定义了 iter() 函数如何返回一个迭代器Iterator。正如前面的示例所示,由于 Python 的 list 对象object已经实现implemented了 __iter__() 方法method,所以我们可以使用 iter(my_list) 将其转换为一个迭代器Iterator。在简单的情况下,我们可以在 __iter__() 方法中直接返回 self

__next__() 定义了产生项目items的方法method。换句话说,它定义了 next() 函数如何获取下一个项目item。

例如,这是一个生成斐波那契数字的类:

from collections.abc import Iterable, Iterator

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 1000:  # set a limitation to stop
            raise StopIteration()
        return self.a


f = Fib()
print(isinstance(f, Iterator))
print(next(f))
print(next(f))
print(next(f))
print(next(f))

# True
# 1
# 1
# 2
# 3

3. 使用生成器Generator

每次都要定义上述两个特殊方法有点复杂。实际上,Python 的生成器机制generator mechanism可以帮助我们完成这些工作。

from collections.abc import Iterable, Iterator

def Fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'


f = Fib(10000)

print(isinstance(f, Iterator))
print(next(f))
print(next(f))
print(next(f))
print(next(f))

# True
# 1
# 1
# 2
# 3

Generator 是 Iterator 的子类。它们之间的关系如下

在这里插入图片描述

Python 中的 for 循环究竟是如何工作的?

到目前为止,我们已经知道了 Iterable 和 Iterator 的所有要点,但还有一点值得解释。 for 循环在 Python 中究竟是如何工作的呢?其实很简单。只需两步:

  • 将可迭代对象Iterable 转换为迭代器Iterator 。
  • 使用 next() 函数获取每个元素,直到停止。

有一个最简单的 for loop 实现,可以帮助您理解。

# convert an Iterable to an Iterator
my_list_iterator = iter(my_list)

while True:
    try:
        # get the next item
        element = next(my_list_iterator)
    except StopIteration:
        # if StopIteration is raised, stop for loop
        break

Conclusion 结论

Python 中的 Iterable 是任何可以迭代的对象。

Iterator 只保存方法而不是项items,它是 Iterable 的子类,以减少时间和空间成本。

Python 中的 For 循环应用这些概念来生成 Iterable 的所有项items。

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

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

相关文章

SpringCloud 和 Linux 八股文第三期五问五答

SpringCloud 和 Linux 八股文第三期五问五答 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;Linux常用命令 2&#xff09;如何查看测试项目的日志 一…

Docker (compose、安装、常用命令整理、compose编排) -day06

一、概念 Docker-Compose就是容器编排&#xff0c;负责实现对Docker容器集群的快速编排 Compose允许用户通过一个单独的docker-compose.yml模板文件&#xff08;YAML 格式&#xff09;来定义一组相关联的应用容器为一个项目&#xff08;project&#xff09;。 可以很容易地用一…

Python数值型字符串校验

从键盘输入一行字符串&#xff0c;编写Python代码判定字符串是python“合法”数值。 (笔记模板由python脚本于2023年12月25日 18:00:52创建&#xff0c;本篇笔记适合熟悉Python符串基本数据类型的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.py…

2023年终总结 —— 我和CSDN相遇的第一年之“技术学习和个人成长的回顾与展望”

​ ​ &#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 &#x1f38a;对2023的总结与回顾&#x1f38a; &#x1f3c5;获奖记录 &#x1f4da;学…

1、gdb基本功能

文章目录 1、gdb1.1、运行1.1.1、程序入参 1.2、断点及观察点1.2.1、设置断点1.2.2、禁用、删除断点1.2.3、观察点 1.3、打印1.3.1、设定打印参数1.3.2、打印数据1.3.3、自动打印1.3.4、按照地址打印 linux下我现在接触到的常用调试工具如下. gbdgdbguicmake-tools gdb是最为通…

SLAM学习入门--传统图像处理

文章目录 传统图像处理颜色空间高斯滤波腐蚀和膨胀开运算和闭运算如何求一张图片的均值&#xff1f;线性插值双线性插值仿射变换透视变换常见的边缘检测算子Sobel 算法Canny 算法Hough 变换原理&#xff08;直线和圆检测&#xff09;找轮廓&#xff08;findCountours&#xff0…

【网络安全 | Misc】Aesop_secret(ISCC)

正文 动态gif&#xff0c;使用工具进行分解&#xff1a; https://tu.sioe.cn/gj/fenjie/ 得到ISCC字样 由Winhex看到密文&#xff1a; U2FsdGVkX19QwGkcgD0fTjZxgijRzQOGbCWALh4sRDec2w6xsY/ux53Vuj/AMZBDJ87qyZL5kAf1fmAH4Oe13Iu435bfRBuZgHpnRjTBn5xsDHONiR3t0Oa8yG/tOKJMN…

故障诊断模型 | Maltab实现PSO-BP粒子群算法优化BP神经网络的故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现PSO-BP粒子群算法优化BP神经网络的故障诊断 模型描述 在机器学习领域,我们常常需要通过训练数据来学习一个函数模型,以便在未知的数据上进行预测或分类。传统的神经网络模型需…

【大模型的前世今生】从自然语言处理说起

自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;被誉为人工智能皇冠上的明珠&#xff0c;是计算机科学和人工智能领域的一个重要方向。它主要研究人与计算机之间&#xff0c;使用自然语言进行有效通信的各种理论和方法。简单来说&#xf…

基于 CefSharp 实现一个文件小工具

I’m not saying you can’t be financially successful I’m saying have a greater purpose in life well beyond the pursuit of financial success Your soul is screaming for you to answer your true calling You can change today if you redefine what success is to …

网络安全—认证技术

文章目录 加密认证对称密钥体制公钥密码体制公钥的加密公钥身份认证和加密 鉴别码认证MAC鉴别码 报文摘要认证认证 加密只认证数字签名 通过了解以前前辈们使用的消息认证慢慢渐进到现代的完整的认证体系。所以在学习的时候也很蒙圈&#xff0c;因为前期的很多技术都是有很严重…

matplotlib单变量和双变量可视化

使用seaborn 库的tips数据集&#xff0c;其中包含了某餐厅服务员收集的顾客付小费的相关数据&#xff08;评论区&#xff09; 单变量可视化 直方图 直方图是观察单个变量最常用的方法。这些值是经过"装箱"&#xff08;bin&#xff09;处理的 直方图会将数据分组后绘…

Vlan的封装模式和端口讲解(Access、Trunk、Hypbrid端口)

目录 Vlan的封装模式 ISL协议 802.1Q协议 二层接口类型 Access接口 Trunk接口 Hybrid接口 不同Vlan之间的通信 Vlan的作用&#xff08;Vlan工作于OSI参考模型的第二层&#xff09; Vlan&#xff08;Virtual Local Area Network&#xff09;虚拟局域网&#xff0c;将一个…

格密码基础:子格,q-ary垂直格与线性代数

目录 一.写在前面 二.子空间垂直 2.1 理论解释 2.2 举例分析 三. 零空间 3.1 零空间与q-ary垂直格 3.2 零空间与行/列空间 四. 格密码相关 一.写在前面 格密码中的很多基础原语都来自于线性代数的基本概念&#xff0c;比如举几个例子&#xff1a; 格密码中的非满秩格…

年底离职了?2024普通人失业怎么创业?2024创业风口!

有多少人会在12月份离职&#xff1f;这是近期热门的话题&#xff0c;年底了&#xff0c;离职潮也来了。是工作压力大?是跟同事相处不好&#xff1f;是公司发展没前景&#xff1f;不&#xff0c;统统都不是。离职无外乎一个原因&#xff1a;工资低&#xff01; 我们除了打工还…

Mybatis 事务接口

当我们从数据源中得到一个可用的数据库连接之后&#xff0c;就可以开启一个数据库事务了&#xff0c;事务成功开启之后&#xff0c;我们才能修改数据库中的数据。 在修改完成之后&#xff0c;我们需要提交事务&#xff0c;完成整个事务内的全部修改操作&#xff0c;如果修改过…

分库分表之Mycat应用学习二

3 Mycat 概念与配置 官网 http://www.mycat.io/ Mycat 概要介绍 https://github.com/MyCATApache/Mycat-Server 入门指南 https://github.com/MyCATApache/Mycat-doc/tree/master/%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%973.1 Mycat 介绍与核心概念 3.1.1 基本介绍 历史&#x…

Tomcat和Servlet

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Tomcat是什么&#xff1f;1.1下载&#xff1a;1.2 tomcat是什么1.3启动服务器&#xff1a; 二.部署三、Servlet3.1创建项目3.2引入依赖pom.xml的所有代码 3…

一文讲清数据资产化之确权和估值

《中共中央 国务院关于构建数据基础制度更好发挥数据要素作用的意见》已发布一年&#xff0c;数据资产化和入表已成为2023年的热门话题&#xff0c;随着2023年底国家数据局吹风《"数据要素x"三年行动计划&#xff08;2024-2026年&#xff09;》即将发布&#xff0c;这…
最新文章