Python 迭代器与生成器

迭代器

迭代器(Iterator)是一个可以记住遍历的位置的对象,该对象包含值的可计数数字,在Python当中:迭代器是实现迭代器协议的对象,它包含方法__iter__() __next__()

__iter__()方法

  • 作用:返回迭代器对象本身

__next__()方法

  • 作用:返回迭代器的下一个元素,如果没有元素了则就会触发StopIteration异常

可迭代对象

如果一个对象/类中,有__iter__()方法并且返回一个迭代器对象,则我们称以这个对象/类创建的对象为可迭代对象。

列表、元组、字典、集合都可以是可迭代的对象。它们都是可迭代的容器,可以从中获取到迭代器

 可以通过dir函数可以列出对象方法

My_list = [1, 2, 3, 4, 5]
a = dir(My_list)
print(a)

实例

My_list = [1, 2, 3, 4, 5]
it = iter(My_list)  # 创建迭代器的对象
print(next(it))  # 输出迭代器的下一个对象
print(next(it))

遍历可迭代对象

我们可以使用for循环来遍历可迭代的对象

my_count = ("one", "tow", "three")

for i in my_count:
  print(i)

创建迭代器

要把对象或者类创建成为迭代器,必须为对象实现__iter__() 方法 和  __next__() 方法

在面向对象编程中类都有一个构造函数,Python的构造函数为__init__(),它会在对象进行初始化的时候执行。

__iter__()方法返回一个特殊的迭代器对象,这个迭代器对象实现了__next__()方法,可以执行操作,但必须返回迭代器对象本身

__next__()方法会返回下一个迭代器对象

实例

class AddOneIterator:
    def __init__(self, start=0):
        self.current = start  # 初始化起始值

    def __iter__(self):
        return self

    def __next__(self):
        self.current += 1
        return self.current
# 创建一个加1的迭代器,从0开始
iterator = AddOneIterator()

# 使用迭代器获取前几个加1后的值
print(next(iterator))  # 输出:1
print(next(iterator))  # 输出:2
print(next(iterator))  # 输出:3
print(next(iterator))  # 输出:4

StopIteration

当我们执行上面代码的时候,可以发现如果有足够的next,或者我们在for循环里面使用,则上面的实例将会一直执行下去。

所以为了防止迭代永远进行,我们可以使用 StopIteration 语句

实例:在next()方法中,我们可以添加一个终止的条件来引发错误

class AddOneIterator:
    def __init__(self, start=0):
        self.current = start  # 初始化起始值

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 10:  # 添加一个if语句
            x = self.current
            self.current += 1
            return x
        else:  # 当大于10的时候终止程序
            raise StopIteration

# 创建一个加1的迭代器,从0开始
iterator = AddOneIterator()

for i in iterator:
    print(i)
输出结果: 1 2 3 4 5 6 7 8 9 10

使用迭代器的好处

  • 节省内存:迭代器允许按需要来生成数据,而不是一次性的将所有数据都加载到内存当中,这对于处理大型数据集非常有效
  • 延迟计算:可以在需要的时候按照需要计算下一个元素,而不是提前计算所有的元素

生成器

生成器是一种特殊的迭代器,它用于创建迭代器

生成器允许你逐个产生值,而不是一次性创建并存储所有值

生成器通过在函数中使用 yield 语句来实现。yield是一个关键字,用于定义生成器函数每次调用生成器函数时,它都会返回一个生成器对象,这个对象可以记住函数执行的位置

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果

实例

def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
for value in gen:
    print(value)
输出结果:1 2 3

实例

def count():
    for i in range(1, 6):  # range的结束索引是不包含的,所以使用6
        yield i

# 使用生成器
c = count()

for number in c:
    print(number)
输出结果:1 2 3 4 5

下面实例为使用yield实现斐波那契数列

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()
输出结果:0 1 1 2 3 5 8 13 21 34 55

使用生成器的好处

  • 节省内存:因为生成器不需要一次性存储所有值
  • 延迟计算:只有在需要时才计算下一个值

迭代器与生成器的区别

  • 内存使用:生成器通常比迭代器更节省内存,因为它们是按需生成值的。
  • 可迭代性:所有生成器都是迭代器,但不是所有迭代器都是生成器。例如,列表是一个迭代器,但不是生成器。
  • 一次性:迭代器可以多次遍历,而生成器在遍历完成后就不能再次使用了,除非你重新创建它。

生成器提供了一种优雅的方式来处理数据流,特别是当数据集很大或者数据是按需生成的时候。而迭代器则提供了一种通用的方式来遍历任何可迭代对象。

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

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

相关文章

Java语法糖写法

一、函数式接口 1、Function函数式接口&#xff1a;有一个输入参数&#xff0c;有一个输出 2、断定型接口&#xff1a;有一个输入参数&#xff0c;返回值只能是布尔值&#xff01; 3、Consumer 消费型接口&#xff1a;只有输入&#xff0c;没有返回值 4、Supplier供给型接口&a…

目标检测讲解

环境准备 pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/simple图片读取&画框 from skimage import io import matplotlib.pyplot as plt import matplotlib.patches as mpss io.imread(dogs.jpg)_, ax plt.subplots(ncols1, nrows1, figsize(6, 6))…

关于Java

关于Java Java语言关于并发JVM调优工具写在最后 Java语言 Java语言作为当下主流开发语言&#xff0c;其面向对象的开发模式以及一次编译多次运行&#xff0c;跨平台运行以及自动的垃圾回收机制可以说是给开发者节省了很大的时间用于逻辑功能的开发&#xff0c;那么在开发过程中…

通信系统的最佳线性均衡器(1)---维纳滤波线性均衡

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在通信领域笔记&#xff1a;…

windows cmd bat 批处理脚本找到监听端口并并杀掉进程 nestat -ano

echo off rem 终止正在监听在端口8888上的进程 rem tokens5 表示第五个token for /f tokens5 %%p in (netstat -ano ^| findstr 8888) do ( set pid%%p ) echo xxxx %pid% rem xxxx TCP [::]:8888 [::]:0 LISTENING 2720 taskkill /pid %pid% /f if %errorlevel% equ 0 ( echo …

ARM功耗管理框架之PPU

安全之安全(security)博客目录导读 思考&#xff1a;功耗管理框架&#xff1f;SCP&#xff1f;PPU&#xff1f;LPI&#xff1f;之间的关系&#xff1f;如何配合&#xff1f; 目录 一、功耗管理框架中的PPU 二、PPU的结构与连接关系 三、PPU操作模式和电源模式及其之间的转…

如何准备大模型面试:迈向成功职业道路的关键一步

前言 在当今日新月异的科技领域中&#xff0c;大模型技术正以其卓越的智能和无限的可能性&#xff0c;吸引着越来越多的企业和求职者。面对大模型领域的职位面试&#xff0c;如何充分准备&#xff0c;展现自己的专业能力和潜力&#xff0c;成为了每位求职者关注的焦点。本文将…

SK投屏助手:电脑控制手机,游戏与App轻松畅玩

SK投屏助手让您将手机画面完美投射至电脑屏幕&#xff0c;而且不止于此&#xff01;现在&#xff0c;您可以利用电脑反向控制手机&#xff0c;轻松操作各种游戏和应用程序。无论是在家中放松还是在工作中提高效率&#xff0c;SK投屏助手都能成为您的得力助手。立即体验无缝连接…

微服务必备容器化技术

文章目录 docker介绍与安装及上手应用什么是容器化技术&#xff1f;为什么需要学习docker&#xff1f;如何理解dockerdocker下载与安装docker的基础组成docker体验 dockerfile介绍并创建go-zero环境容器docker的基础组成从容器构建属于go环境的容器基于dockerfile构建go容器镜像…

没有名为 keras.preprocessing 的模块

估计是因为版本原因 我安装的是 3.3.3版本 >>> import keras >>> print(keras.__version__) 3.3.3 keras.preprocessing.image 将 keras.preprocessing.image 改为 from keras_preprocessing.image 之后报image_type啥的错误&#xff0c;后面查找之后…

java问题解决: IDEA java 警告 源发行版 17 需要目标发行版 17

效果图 问题原因 jdk和你实际安装的jdk不匹配 解决问题 1.点击File -->Project Structure–>Project 修改这两处 2. 在Project Structure–>Modules中的红框位置都要调整对应版本 3、点击File–>settings–>java compile将对应框的版本修改成对应版本即可–改…

运算放大器(运放)缓冲器(跟随器)电路

运算放大器(Operational Amplifier) 运算放大器(Operational Amplifier)是一种差分放大器&#xff0c;具有高输入电阻、低输出电阻、高开放增益&#xff08;开环增益&#xff09;&#xff0c;并具有可放大输入引脚与-输入引脚间的电压差的功能。 设计目标 输入输入输出输出频…

揭开AI大模型的神秘面纱:一文看懂GPT-4的核心技术

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;特别是AI大模型的崛起&#xff0c;给人们的生活和工作带来了深远的影响。作为其中的佼佼者&#xff0c;GPT-4备受瞩目。那么&#xff0c;GPT-4的核心技术究竟是什么&#xff1f;它是如何运作的&a…

Chrome插件开发入门:手把手教你创建第一个扩展

问题背景 最近&#xff0c;客户发布了一个新的任务 —— 开发一个Chrome插件。之前没有这方面的开发经验&#xff0c;准备想学习一下这块的内容&#xff0c;我发现网上的大多数视频都是几年前的&#xff0c;开发版本都是基于MV2&#xff0c;当前谷歌已经开始使用MV3&#xff0…

python使用哪种数据库

MySQL 是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#xff0c;关…

python flask配置邮箱发送功能,使用flask_mail模块

&#x1f308;所属专栏&#xff1a;【Flask】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点…

【C++高阶】高效搜索的秘密:深入解析搜索二叉树

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;C多态 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀二叉搜索树 &#x1f4d2;1. 二叉搜索树&…

学习笔记——路由网络基础——路由度量值

3、路由度量值 (1)基本概念 路由度量值表示到达这条路由所指目的地址的代价。度量值数值越小越优先&#xff0c;度量值最小路由将会被添加到路由表中。度量值很多时候被称为开销(Cost)。 路由度量(路由开销 cost)对于同一个路由协议&#xff0c;当到达某目标网段有多条路由供…

适配不同数据库厂商方案

背景 在对国产化数据有要求的时候&#xff0c;我们会做对 达梦、海量等数据库的配置。 有些SQL 以前没有写成标准SQL&#xff1b; 那么适配的时候怎么办呢&#xff1f;改成标准SQL。 如果不好改呢&#xff1f;比如SQL比较复杂等&#xff0c;需要判断 当前是哪个厂商的数据库…

HTML星空特效

目录 写在前面 完整代码 代码分析 运行效果 系列文章 写在后面 写在前面 100行代码实现HTML星空特效。 完整代码 全部代码如下。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g…