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

迭代器、生成器

时间:2023-12-13 16:11:41浏览次数:31  
标签:__ 迭代 对象 生成器 yield my

【一】迭代器

迭代器(Iterator)是Python中用于遍历可迭代对象的一种机制。可迭代对象是指那些可以被迭代的对象,例如列表、元组、字符串、集合、字典。迭代器提供了一种顺序访问可迭代对象元素的方式,而不需要事先知道对象的内部结构。

迭代器是通过实现两个特殊方法来工作的:

  1. __iter__()方法:该方法返回迭代器对象本身。在迭代过程中,会首先调用可迭代对象的__iter__()方法,获取迭代器对象。

  2. __next__() 方法是迭代器对象中的一个特殊方法,它定义了在迭代过程中获取下一个元素的逻辑。

当我们使用迭代器对象进行迭代操作时,会重复调用__next__()方法来获取迭代序列中的下一个元素。每次调用该方法时,迭代器会返回序列中的下一个元素,直到序列中没有更多的元素可供迭代,此时迭代器会引发 StopIteration 异常来终止迭代。

迭代器的使用方式如下:

my_iterable = [1, 2, 3, 4, 5]  # 可迭代对象

my_iterator = iter(my_iterable)  # 获取迭代器对象

print(next(my_iterator))  # 输出:1
print(next(my_iterator))  # 输出:2
print(next(my_iterator))  # 输出:3
# ...

# 或者使用 for 循环遍历迭代器
for item in my_iterator:
    print(item)
输出结果:
1
2
3
4
5

list1 = [1, 2, 3, 4, 5]  
list2 = (list1.__iter__())  # <list_iterator object at 0x000002286570A650>  
print(list2.__next__())  # 1  
print(next(list2))  # 2  
  
  
str1 = 'dream'  
str2 = str1.__iter__()  
print(str2.__next__())  # d  
print(next(str2))  # r

通过迭代器,可以逐个访问可迭代对象中的元素,而不需要直接访问它们的索引。这在处理大型数据集或需要延迟加载元素的情况下非常有用,因为迭代器只在需要时生成下一个元素,节省了内存空间。

1.1 __iter__()

当迭代器对象调用__iter__()方法后,它会返回迭代器对象本身。在Python中,迭代器对象本身就是可迭代对象,因此调用__iter__()方法后返回的是迭代器对象本身。这是为了确保迭代器对象可以被正确地使用在需要可迭代对象的上下文中。

迭代器对象实现了__iter__()方法是为了满足可迭代对象的要求,因为可迭代对象需要提供一个返回迭代器的方法。通过返回迭代器对象本身,迭代器对象可以在需要可迭代对象的场景中使用,例如在for循环中进行迭代操作。

需要注意的是,迭代器对象本身也必须实现__next__()方法,以便能够提供下一个元素。迭代器对象的__next__()方法定义了如何获取下一个元素,而__iter__()方法则用于返回迭代器对象本身。这样,迭代器对象既可以作为可迭代对象被使用,又可以作为迭代器对象进行迭代操作。

以下是一个示例,演示了迭代器对象调用__iter__()方法后返回迭代器对象本身:

my_iterable = [1, 2, 3, 4, 5]  # 可迭代对象

my_iterator = iter(my_iterable)  # 获取迭代器对象

print(my_iterator.__iter__() is my_iterator)  # 输出:True

【二】生成器

生成器是一种特殊的迭代器,它可以通过函数的方式来创建。与常规的迭代器相比,生成器更加简洁和高效。

生成器函数使用yield语句来定义,当函数执行到yield语句时,会暂停函数的执行并返回一个值给调用者。下次调用生成器函数时,函数会从上次暂停的地方继续执行,直到再次遇到yield语句。

生成器函数可以通过循环、条件语句和其他逻辑来动态生成值,而不需要一次性生成所有的值。这种延迟生成的特性使得生成器非常适合处理大量数据或无限序列。

下面是一个简单的生成器函数的示例,演示了生成器的基本用法:

def my_generator():
    yield 1
    yield 2
    yield 3

# 创建生成器对象
gen = my_generator()

# 使用生成器对象进行迭代
for item in gen:
    print(item)

在上述示例中,my_generator() 函数是一个生成器函数,它通过使用 yield 语句来定义生成器的逻辑。每次调用生成器函数时,它会返回一个值,并在下次调用时从上次离开的地方继续执行。

生成器对象可以像迭代器一样进行迭代,因此我们可以使用 for 循环来遍历生成器对象并获取生成器生成的值。

总结来说,生成器是一种通过函数来创建的特殊迭代器,它具有延迟生成值的特性,能够高效地处理大量数据或无限序列。

2.1 yield + send 使用方式

生成器的send方法用于向生成器发送数据,并在生成器内部使用yield语句接收这些数据。它可以用来实现生成器与调用者之间的双向通信。

要使用send方法,首先需要创建一个生成器对象,然后可以使用end方法向生成器发送数据。生成器会从上一次yield语句的位置继续执行,并将发送的数据作为yield表达式的返回值。调用send方法后,生成器会暂停,直到下一次调用生成器的迭代方法(如next)或再次调用send方法。

下面是一个简单的示例,演示了如何使用send方法向生成器发送数据:

def my_generator():  
    while True:  
        received = yield  
        print('Received:', received)  
  
  
# 创建生成器对象  
gen = my_generator()  
  
# 启动生成器  
next(gen)  
  
# 使用send方法发送数据  
gen.send('Hello')  
gen.send('World')

在上述示例中,我们定义了一个生成器函数my_generator(),它使用yield语句接收数据并打印接收到的数据。我们创建了生成器对象gen,然后通过调用next(gen)启动生成器。

接下来,我们使用gen.send('Hello')gen.send('World')分别向生成器发送了两个字符串。生成器会从上一次yield语句的位置继续执行,并将发送的数据作为yield表达式的返回值打印出来。

第一次调用生成器的send方法之前必须先调用一次next(gen),用于启动生成器。此外,在生成器内部的第一个yield语句之前不能使用send方法,否则会引发TypeError

标签:__,迭代,对象,生成器,yield,my
From: https://www.cnblogs.com/wx-x/p/17899274.html

相关文章

  • 生成器
    生成器Python中的生成器是一种特殊的迭代器,可以在需要时生成数据,而不必提前从内存中生成并存储整个数据集。通过生成器,可以逐个生成序列中的元素,而无需一次性生成整个序列。生成器在处理大数据集时,具有节省内存、提高效率的特点。迭代器不一定是生成器,生成器一定是迭代器。......
  • 迭代器失效问题总结
    关于迭代器失效,,今天做一个总结。迭代器失效分三种情况考虑,也是三种数据结构考虑,分别为数组型,链表型,树型数据结构。1、对于序列式容器,比如vector,删除当前的iterator会使后面所有元素的iterator都失效。举例如下:voidvectorTest(){vector<int>v;for(inti=0;i<10;i+......
  • 迭代器
    可迭代对象可迭代对象有:集合,列表,字符串,字典,元组不可迭代:整数,浮点数,布尔迭代器对象调用obj.__iter__()方法返回的结果就是一个迭代器对象迭代器对象是内置有iter和next方法的对象,打开的文件本身就是一个迭代器对象执行迭代器对象.iter()方法得到的仍然是迭代器本身而执......
  • 迭代器和生成器
    迭代器什么是迭代器迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代。为何要有迭代器迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型有:列表,字符串,元组,字典,集合,打开文件文件是可迭代对象,也是迭代器......
  • 实验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......