首页 > 编程语言 >浅析python中的生成器和迭代器

浅析python中的生成器和迭代器

时间:2023-04-19 10:12:18浏览次数:50  
标签:__ 迭代 python 生成器 next gg print 浅析

一、什么叫生成器?

Python中,一边循环一边计算的机制,称为生成器:generator

二、怎么创建生成器

1.生成器表达式()
生成器表达式返回一个生成器对象,需要用一个变量名来接收
g = (x*3 for x in range(5))
# 打印g,返回一个生成器对象
print(g) # <generator object <genexpr> at 0x000002125FA1DA50>


2.生成器函数
def generation():
    print('hello1')
    yield 1
    print('hello2')
    yield 2
    print('hello3')
    yield 3
        
gg = generation()
# 打印gg,返回一个生成器对象
print(gg) # <generator object generation at 0x000002125FA1D740> :函数未立即执行,返回一个生成器对象

next(gg) # 返回hello1, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止
next(gg) # 返回hello2, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止
next(gg) # 返回hello3, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止 
next(gg) # 返回StopIteration
说明:从上面可以看到‘generation’函数没有使用return作为返回值,而是使用了yield作为返回值。
      一个带有yield作为返回值的函数为生成器函数。当我们使用yield时,它帮我们自动创建了__iter__()
      和next()方法,在没有数据时,会抛出stopIteration异常。
简述函数执行过程:
a.调用函数generation(),返回一个生成器对象
b.第1次使用next(gg),函数开始执行,返回hello1,遇到yield关键字,函数停止执行,并记录当时执行的位置'1'
c.第2次使用next(gg),函数从'1'处,开始执行,返回hello2,遇到yield关键字,函数停止执行,并记录当时执行的位置'2'
d.第3次使用next(gg),函数从'2'处,开始执行,返回hello3,遇到yield关键字,函数停止执行,并记录当时执行的位置'3'
e.第4次使用next(gg),函数从'3'处,开始执行,但是3后面没有语句了此时会抛出异常‘StopIteration’ 

从上面可以看到写4个next(gg),可不可以不写这么多?
答:可以,可以用for循环来代替
for i in gg:
    print(i)
# i的返回值,当使用for循环对迭代器对象进行循环时,会返回yield的返回值
hello1
1
hello2
2
hello3
3

 

三、什么叫迭代器?

在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 __iter__() 和 __next__()

创建迭代器

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

正如 Python 类/对象 ,所有类都有名为 __init__() 的函数,它允许您在创建对象时进行一些初始化。

__iter__() 方法的初始化迭代器对象。

__next__() 方法进行迭代

class MyNumbers:
  def __iter__(self):
    self.a = 1  # 初始化
    return self  # 返回迭代器对象本身   

  def __next__(self):
    x = self.a
    self.a += 1  # 迭代
    return x

myclass = MyNumbers()  # 实例化对象,创建命名空间
myiter = iter(myclass)  # 使用iter方法进行迭代

print(next(myiter))  # 1
print(next(myiter))  # 2
print(next(myiter))  # 3
print(next(myiter))  # 4
print(next(myiter))  # 5

 

Python 迭代器的好处

使用迭代器的好处是可以节省资源。

  • 代码减少。

  • 代码冗余得到极大解决。

  • 降低代码复杂度。

  • 它为编码带来了更多的稳定性。

 

 四、可迭代对象

可以实现iter方法,可以用for…in…进行遍历的对象

可以使用python内置数isinstance()来判断一个对象是否属于可迭代对象

from typing import Iterable
# 列表
a = isinstance([1, 2, 3], Iterable)
print(a)  # True

# 字符串
b = isinstance('1', Iterable)
print(b)  # True

# 整数
c = isinstance(1, Iterable)
print(c)  # False

# 元组
d = isinstance((1, 2, 3), Iterable)
print(d)  # True

# 字典
e = isinstance({'name': 'anna'}, Iterable)
print(e)  # True

# 集合
f = isinstance({'age'}, Iterable)
print(f)  # True

列表、字符串、元组、字典、集合都是可迭代对象,而整数不是可迭代对象

 

注意:可迭代对象不是迭代器 

 下面将可迭代对象转化为迭代器

from typing import Iterable, Iterator

l1 = ['name', 'age', 'sex']
a = isinstance(l1, Iterable)  # 判断对象是否为可迭代对象
aa = isinstance(l1, Iterator)  # 判断对象是否为迭代器
print(a)  # True
print(aa)  # False

'''
根据迭代器定义,迭代器使用__iter__()方法初始化迭代器对象,使用__next__()方法进行迭代;
而可迭代对象只实现了__iter__()方法,但是没有实现__next__()方法,所以不是迭代器
'''
可以使用iter()方法将可迭代对象转化为迭代器
iterator_a = iter(l1)
print(type(iterator_a),isinstance(iterator_a, Iterator))  # <class 'list_iterator'> , True

 

 结论:每个迭代器都是可一迭代的,可以迭代的对象不一定是迭代器

 

标签:__,迭代,python,生成器,next,gg,print,浅析
From: https://www.cnblogs.com/zy7941246/p/17332300.html

相关文章

  • Python常见问题总结
    对于长期深耕在python爬虫的程序员来说,如何快速解决代码中的问题它是作为合格的程序员应该具备的基本素质。下面将我总结整理出有关python的一些常见问题记录下来方便后期查证。Pythonpython没有多态,而是鸭子类型多继承,没有接口,可通过语法糖实现接口的作用lambda中只能有一句......
  • LeetCode Top100: 反转链表 (python)
     给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例1:输入:head=[1,2,3,4,5]输出:[5,4,3,2,1]示例2:输入:head=[1,2]输出:[2,1]示例3:输入:head=[]输出:[] 提示:链表中节点的数目范围是 [0,5000]-5000<=Node.val<=5000实现:给你......
  • 几款主流的Python开发板对比
    几款主流的Python开发板对比下面正式进入我们的主题。随着Python语言的日渐普及和大众化,一些专门用于Python语言的微控制器的板子已经呈现到公众面前。在单片机上可以跑的Python又称MicroPython,MicroPython是Python3编程语言的一个简洁和快速实现,专门优化运行于一个微控制器上......
  • 【THM】Python Basic(Python基础)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/pythonbasics本文相关内容:使用基于网络的代码编辑器,学习Python的基础知识,并将你的知识付诸实践。Python简介在本文中,你将亲身体验并学习脚本编程语言Python,学会编程允许你创建一些安全工具以及创建脚本,这将帮助你......
  • LeetCode Top100: 翻转二叉树(python)
    给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例1:输入:root=[4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1]示例2:输入:root=[2,1,3]输出:[2,3,1]示例3:输入:root=[]输出:[] 提示:树中节点数目范围在 [0,100] 内-100<=Node.val<=100实......
  • LeetCode Top 100: 二叉树的直径 (python)
     给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。 示例:给定二叉树1/\23/\45返回 3,它的长度是路径[4,2,1,3]......
  • 关于PythonNet与TensorFlow的调试技巧
    1.使用TensorFlow2.x版本训练的模型,在导入时容易报错,不要跨版本训练或者调用模型。报错内容通常定位到restore方法。2.PythonNet调用py文件报错时,右键该文件执行后报错内容会一闪而过,可以右键使用Python编译器(Idel)打开,错误会详细显示,且内容与编辑器一样。3.TensorFlow1.9最......
  • 教你用Python画哆啦A梦、海绵宝宝、皮卡丘、史迪仔!
    一、哆啦A梦  由于代码过长,这里仅显示部分代码:fromturtleimport*importturtleastfromrandomimport*#五轨迹跳跃defmy_goto(x,y):penup()goto(x,y)pendown()defeyes():fillcolor('#ffffff')begin_fill()tracer(False)......
  • 【Python毕业设计】基于Python+Flask+MySQL的学生信息管理系统(附完整源码)
    1、项目说明基于python+Flask+mysql的学生信息管理系统项目实战项目需要安装pycharm专业版,mysql数据库以及项目所需的所有模块创建数据库名称db_online_notes,然后执行sql文件生成数据表和数据项目需要安装flask,pymysql以及其他的一些模块安装命令如下:pipinstall-ihttps://......
  • 记一次python写爬虫爬取学校官网的文章
    有一位老师想要把官网上有关数字化的文章全部下载下来,于是找到我,使用python来达到目的首先先查看了文章的网址获取了网页的源代码发现一个问题,源代码里面没有url,这里的话就需要用到抓包了,因为很明显这里显示的内容是进行了一个请求,所以只能通过抓包先拿到请求的url从而获得每一......