首页 > 其他分享 >迭代器和生成器

迭代器和生成器

时间:2023-12-12 14:56:48浏览次数:24  
标签:__ .__ 迭代 生成器 iter next print

迭代器

什么是迭代器

迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代。

为何要有迭代器

迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型有: 列表,字符串,元组,字典,集合,打开文件

文件是可迭代对象,也是迭代器

with open("关于成长.txt", "wt", encoding="utf-8") as file_obj:
    file_obj.write("你懂的越多,你就越像这个世界的孤儿。")

with open("关于成长.txt", "rt", encoding="utf-8") as file:
    file_iter = file.__iter__()  # file_iter = iter(file)
    print(file_iter.__next__())
    print(file_iter.__next__())
Traceback (most recent call last):
  File "E:\xxx.py", line 13, in <module>
    print(file_iter.__next__())
StopIteration
hero_list = ["小满", "大乔", "王昭君"]
index = 0

while index < len(hero_list):
    print(hero_list[index])
    index += 1
小满
大乔
王昭君

上述迭代取值的方式只适用于有索引的数据类型:列表、字符串、元组

为了解决基于迭代器取值的局限性 python必须提供一种能够不依赖于索引的取值方式,这就是迭代器

如何使用迭代器

什么是可迭代对象

但凡内置有__iter__方法的,都称之为可迭代对象

可迭代对象(iterable)指的是可以依次返回其内部成员的对象。比如字符串、列表、字典、文件等都是可迭代对象。从语法方面说就是那些具有__iter__的方法的对象,对于类来说指的是那些具有__getitem__方法的对象。

s1 = ''  # 字符串
s1.__iter__()
 
l = [] # 列表
l.__iter__()

t = (1,)  # 元组
t.__iter__()

d = {'name': '小满'}  # 字典
d.__iter__()

set1 = {1, 2, 3}  # 集合
set1.__iter__()

with open('迭代对象.txt', mode='w', encoding='utf-8') as f:  # 文件
    f.__iter__()
	f.__next__()

如何使用迭代器

调用可迭代对象下的__iter__方法,会将其转成迭代器对象

dic = {"a": 1, "b": 2, "c": 3}
dic_iterator = dic.__iter__()  # 相当于iter(dic)

print(dic_iterator.__next__())  # 相当于next(dic_iterator)
print(dic_iterator.__next__())
print(dic_iterator.__next__())
print(dic_iterator.__next__())
a
b
c
Traceback (most recent call last):
  File "E:\xxx.py", line 12, in <module>
    print(dic_iterator.__next__())
StopIteration

在一个迭代器取值干净的情况下,再对其取值取不到。

dic = {"a": 1, "b": 2, "c": 3}
items = dic.__iter__()

while True:
    try:
        print(items.__next__())
    except StopIteration:
        break
print("==========>")

while True:
    try:
        print(items.__next__())  # 取不到了
    except StopIteration:
        break

a
b
c
==========>

如果想再取一次怎么办?重新赋值一次

dic = {"a": 1, "b": 2, "c": 3}
items = dic.__iter__()

while True:
    try:
        print(items.__next__())
    except StopIteration:
        break
print("==========>")

items = dic.__iter__()
while True:
    try:
        print(items.__next__())  # 取不到了
    except StopIteration:
        break
a
b
c
==========>
a
b
c

可迭代对象与迭代器对象详解

可迭代对象可以转成成迭代器对象:内置有__iter__方法的对象。

可迭代对象.__iter__()得到迭代器对象

迭代器对象:内置有__iter__方法并且内置有__next__方法的对象

迭代器对象.__next__():得到迭代器的下一个值
迭代器对象.__iter__():得到迭代器本身,说白了调了跟没调一样

看案例

dic = {"a": 1, "b": 2, "c": 3}
items = dic.__iter__()

print(items is items.__iter__().__iter__().__iter__().__iter__())

True

迭代器优缺点

优点

为序列和非序列类型提供了一种统一的迭代取值方式;

惰性取值;每次只取一个数据,不占内存;迭代器保存的是产生数据的算法,而不是实际的数据

缺点

除非取尽,否则无法获取迭代器的长度;

只能往后依次取值,不能返回头往前取值。就像象棋中的卒,只进不退。

for循环的工作原理

for循环可以称之为迭代器循环

  1. dic.__iter__()得到一个迭代器对象
  2. 迭代器对象.__next__()拿到一个返回值,然后将该返回值赋值给for index in ...中的index
  3. 循环往复步骤2,直到抛出异常StopIteration异常for循环会捕捉异常然后结束循环

list("hello")原理同for循环

生成器

如何自定义生成器:

在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,会返回一个生成器对象,生成器即自定义的迭代器。 如果取完了一样会报StopIteration错误

def func():
    print("第1次")
    yield 1
    print("第2次")
    yield 2
    print("第3次")
    yield 3
    print("第4次")


g = func()

# 会触发函数体代码的运行,遇到yield停下来,将yield后面的值当做本次调用后的返回结果
res = g.__next__()  # next(g)
print(res)

res2 = g.__next__()
print(res2)

res3 = g.__next__()
print(res3)

res4 = g.__next__()
print(res4)
第1次
1
第2次
2
第3次
3
第4次
报错 StopIteration

应用案例

def my_range(start, stop, step=1):
    print("start...")

    while start < stop:
        yield start
        start += step
    print("end...")


res = my_range(1, 5, 2)
print(next(res))  # res.__next__()
print(next(res))  # res.__next__()
print(next(res))  # res.__next__()

start...
1
3
end...
报错:StopIteration
def my_range(start, stop, step=1):
    print("start...")

    while start < stop:
        yield start
        start += step
    print("end...")


for index in my_range(1, 9, 2):
    print(index)
start...
1
3
5
7
end...

yield的表达形式

def hero(name):
    print(f"{name}准备吃东西啦...")
    while True:
        # food拿到的就是yield接收的值
        food = yield
        print(f"{name}吃了{food}")


g = hero("小满")
g.send(None)  # 等同于 next(g)
g.send("红buff")
g.send("蓝buff")
g.close()  # 关闭后无法传值

g.send("红buff")
小满准备吃东西啦...
小满吃了红buff
小满吃了蓝buff
报错:StopIteration

标签:__,.__,迭代,生成器,iter,next,print
From: https://www.cnblogs.com/ccsvip/p/17896860.html

相关文章

  • 实验18:迭代器模式
    本次实验属于模仿型实验,通过本次实验学生将掌握以下内容: 1、理解迭代器模式的动机,掌握该模式的结构;2、能够利用迭代器模式解决实际问题。 [实验任务一]:JAVA和C++常见数据结构迭代器的使用信1305班共44名同学,每名同学都有姓名,学号和年龄等属性,分别使用JAVA内置迭代器和C++中......
  • Mybatis使用generator逆向工程生成器生成entity、mapper、.xml模版类
    前言今天将表建好了,但是一个一个的建实体类、Mapper接口、Mapper.xml文件就十分的麻烦,所以我就想到了MyBatis逆向,今天就操作一把!这里我们采用maven来进行操作。一、新建generatorConfig.xml文件首先建好表,在你的项目的resource文件中新建generatorConfig.xml文件。代码如下:<?xmlv......
  • 迭代器模式
    本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解迭代器模式的动机,掌握该模式的结构;2、能够利用迭代器模式解决实际问题。1. 搜集并掌握JAVA和C++中常见的数据结构和迭代器的使用方法,例如,vector,list,map和set等;JavaPriorityQueuejavaimportjava.util.Pr......
  • 【scikit-learn基础】--『数据加载』之样本生成器
    除了内置的数据集,scikit-learn还提供了随机样本的生成器。通过这些生成器函数,可以生成具有特定特性和分布的随机数据集,以帮助进行机器学习算法的研究、测试和比较。目前,scikit-learn库(v1.3.0版)中有20个不同的生成样本的函数。本篇重点介绍其中几个具有代表性的函数。1.分类聚类......
  • python的异步迭代器含义
    python的异步迭代器什么意思?什么是迭代器:迭代器是一种遵循迭代器协议的对象,可以被用在像for循环这样的迭代环境中。迭代器协议包含两个方法:__iter__():返回迭代器自身。__next__():返回迭代器的下一个元素。如果没有更多元素,则抛出StopIteration异常。就是这两个方法要包......
  • mybatis-plus 新版代码生成器模板
    publicclassCodeGenerator{publicstaticvoidmain(String[]args){//数据源配置FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/xdclass?useUnicode=true&characterEncoding=utf-8&useSSL=false","root",&qu......
  • 设计模式(十六)迭代器
    一、定义提供一种方法顺序访问一个聚合对象中的各个元素,且不用暴露该对象的内部表示。迭代器模式是一种对象行为型模式,又称为游标(Cursor)模式。二、描述在软件系统中,聚合对象拥有两个职责:一是存储数据,二是遍历数据。从依赖性来看,前者是聚合对象的基本职责,而后者既是可变化的,又是......
  • 迭代器和生成器、异常捕获
    一、迭代器(Iterator)1、可迭代对象(Iterable)和可索引对象存储了元素的一个容器对象,且容器中的元素可以通过“__iter__()”方法或“__getitem__()”方法访问。可迭代对象不能独立进行迭代,可通过“for…in”遍历来完成2、常见的可迭代对象字符串、列表、元组、字典、集合、文件......
  • python 可迭代对象 迭代器 生成器
    一个对象若要用for循环则需实现def__iter__(self,item)或def__iter__(self,item)方法可迭代对象实现了def__iter__(self,item)方法  迭代器  实现了def__iter__(self,item)和def__next__(self)方法  迭代器一定是可迭代对象可迭代对象不一定是迭代器from......
  • Unity DOTS系列之System中如何使用SystemAPI.Query迭代数据
    最近DOTS发布了正式的版本,我们来分享一下System中如何基于SystemAPI.Query来迭代World中的数据,方便大家上手学习掌握UnityDOTS开发。SystemAPI.Query的使用System有两种,一种是Unmanaged的ISystem,一种是managed的SystemBase,这两种System都可以通过SystemAPI.Query来迭代与......