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

生成器和迭代器

时间:2023-11-05 23:58:07浏览次数:37  
标签:函数 迭代 生成器 yield next 内存

一,生成器和迭代器的区别

 

生成器和迭代器在Python中都用于处理迭代操作,但它们之间存在一些关键区别。

  1. 实现方式:

    • 迭代器是一个单一的、不可更改的对象,用于遍历(即迭代)一个容器对象(如列表、元组、字典等)。要创建一个迭代器,需要定义一个类并实现两个方法:__iter__() 和 __next__()
    • 生成器是一种特殊的迭代器,它使用一个函数来创建迭代器。与常规函数不同,生成器可以在执行过程中暂停并恢复,以产生迭代器。要创建一个生成器,需要定义一个函数并使用关键字yield来返回每个迭代器。
  2. 内存使用:

    • 迭代器在创建时需要将整个容器加载到内存中。因此,如果容器非常大,则使用迭代器可能会占用大量内存。
    • 生成器不需要一次性加载整个容器到内存中。相反,它可以根据需要在每次迭代时生成新的值。这对于处理大量数据非常有用,因为它可以节省内存并提高性能。
  3. 用途:

    • 迭代器主要用于遍历容器对象。它们通常与for循环一起使用。
    • 生成器主要用于需要延迟计算的场景,例如处理大量数据或无限序列。它们非常适合用于大数据集,因为它们可以节省内存并提高性能。生成器还可以用于实现装饰器和生成器表达式等高级功能。
  4. 返回值:

    • 迭代器的__next__()方法返回容器的下一个值。当容器中没有更多元素时,它将引发StopIteration异常。
    • 生成器的__next__()方法也返回容器的下一个值,但当容器中没有更多元素时,它将引发StopIteration异常。此外,生成器还可以使用关键字yield在函数内部生成新的值。

总之,生成器和迭代器都用于处理迭代操作,但它们在实现方式、内存使用、用途和返回值方面有所不同。生成器更适合用于延迟计算和处理大量数据集,而迭代器主要用于遍历容器对象。

 

二,生成器中yield关键字的意义

 

在Python中,yield关键字在生成器(generator)中起着非常重要的作用。生成器是一种特殊的迭代器,允许你在需要时生成数据,而不是一次性生成所有数据。yield关键字用于在生成器函数中定义生成器。

当你在一个函数中使用yield时,该函数将变成一个生成器函数,而不是常规的函数。每次从生成器中请求一个值时,Python将执行该函数直到遇到yield语句,然后暂停该函数并将控制权返回给请求者。当请求者完成后,生成器将恢复并继续执行,直到遇到另一个yield或到达函数末尾。

yield关键字的意义在于它允许你创建一种延迟计算的机制,即只在需要时生成数据。这对于处理大量数据或无限序列非常有用,因为它可以节省内存并提高性能。

以下是一个使用yield的简单示例:

 

def simple_generator():  
    yield "Hello"  
    yield "World"  
    yield "!"  
  
# 创建生成器对象  
gen = simple_generator()  
  
# 请求第一个值  
print(next(gen))  # 输出:Hello  
  
# 请求第二个值  
print(next(gen))  # 输出:World  
  
# 请求第三个值  
print(next(gen))  # 输出:!

 

三,如果我用迭代器的方法,读取一个大文件,如何读呢

 

def read_large_file(file_path):  
    with open(file_path, 'r') as file:  
        for line in file:  
            yield line  
  
# 使用生成器读取文件  
for line in read_large_file('large_file.txt'):  
    # 处理每一行的内容  
    print(line)

 

在上面的代码中,我们定义了一个名为read_large_file的生成器函数,它接受一个文件路径作为参数,并使用with open语句打开文件。然后,我们使用for循环逐行读取文件,并使用yield语句将每一行的内容返回给调用者。

在主程序中,我们使用read_large_file函数来读取大文件,并使用for循环遍历生成器返回的每一行内容进行处理。由于使用生成器逐行读取文件,因此不会一次性将整个文件加载到内存中,从而有效地减少了内存占用。

 

四,生成器的原理

 

生成器的底层原理是基于Python的迭代器协议。生成器是一种特殊的迭代器,它使用函数中的yield语句来定义生成器的迭代器接口。当生成器被调用时,它返回一个特殊的迭代器对象,这个对象包含了指向生成器函数的指针以及初始状态。

在生成器函数中,使用yield语句来返回一个值,并将执行状态保存下来。当生成器再次被调用时,它会从上次离开的位置开始执行,直到遇到另一个yield语句或者函数结束。这个过程会反复进行,直到生成器中的所有元素都被迭代完毕。

在底层,生成器使用了堆内存来存储生成器的状态和返回的值。当生成器被调用时,它会在堆内存中分配一块内存来保存当前的状态和返回的值。当生成器再次被调用时,它会从堆内存中取出上次的状态和值,并继续执行。

生成器的底层原理还包括了对异常的处理。在生成器函数中,可以使用tryexcept语句来捕获和处理异常。当生成器函数中发生异常时,生成器会抛出异常,并停止迭代。

总之,生成器的底层原理是基于Python的迭代器协议和堆内存存储来实现的。它能够以一种简洁的方式处理大数据量和耗时操作的场景,并且具有高效的空间利用率和灵活的异常处理能力。

 

五,next()方法的使用

 

next()方法是Python中的一个内置函数,用于获取迭代器的下一个值。它接受一个迭代器对象作为参数,并返回迭代器中的下一个值。如果迭代器已经耗尽,则next()方法会引发StopIteration异常。

下面是一个使用next()方法的简单示例:

# 创建一个迭代器对象  
it = iter([1, 2, 3, 4, 5])  
  
# 使用next()方法获取迭代器的下一个值  
print(next(it))  # 输出:1  
print(next(it))  # 输出:2  
print(next(it))  # 输出:3

 

在上面的示例中,我们首先创建了一个迭代器对象it,它包含了列表[1, 2, 3, 4, 5]。然后,我们使用next()方法来依次获取迭代器中的下一个值,并打印出来。

需要注意的是,如果迭代器已经耗尽,再次调用next()方法会引发StopIteration异常。为了避免这种情况,可以使用try...except语句来捕获异常并进行处理。

标签:函数,迭代,生成器,yield,next,内存
From: https://www.cnblogs.com/chaojiyingxiong/p/17811594.html

相关文章

  • 【数值分析】第6章-解线性方程组的迭代法
    第6章-解线性方程组的迭代法\[A\vec{x}=\vec{b}\Leftrightarrow\vec{x}=B\vec{x}+\vec{f}\]建立迭代\[\vec{x}^{(k+1)}=B\vec{x}^{(k)}+\vec{f}\]B称为迭代矩阵Jacobi迭代的矩阵形式\[\begin{align}A\vec{x}=\vec{b}&\Leftrightarrow(D+L+U)\vec{x}=......
  • 使用C++实现Range序列生成器
    在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间......
  • 使用C++实现Range序列生成器
    在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间,......
  • Java拾贝第十五天——集合之Iterator迭代器
    虽然foreach循环可以遍历集合输出,但书上提及了一个观点。只要碰到了集合输出的操作,就一定要使用Iterator(迭代器)接口实际上编译器把foreach循环通过Iterator改写为了普通的for循环上述的观点在本文最后一部分会提及。IteratorIterator是专门的迭代输出接口,所谓迭代就是将......
  • 迭代加深,双向搜索,IDA*,A*,双端队列BFS
    迭代加深://迭代加深搜索//给搜索设定一个范围,如果在这个范围内没有答案那么再加大搜索范围//这么做是为了防止搜索过深,导致利用大量时间搜索无用信息//如果当前搜索是第10位,搜索的是个二叉树,那么前9个就是2^0+2^1+2^2+..+2^9=2^10-1,所以时间复杂度并没增大太多//htt......
  • fibnacci数列递归/迭代实现
    什么是fibnacci数列?斐波那契数列(Fibonaccisequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(LeonardoFibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:F(0)=1,F(1)=1,F(n)=F(n-1)+F(n-......
  • 代码生成器 CodeBuilder 3.2 正式版发布
    CodeBuilder是一款强大的代码生成工具,目前发布了3.2版本,大家可以前去下载体验官方主页。1、多种数据源基于ADO.NET的数据驱动PowerDesignerPDManerDbSchemaSwagger这几种数据源基本上已经覆盖了我们常用的数据环境了,如果你有能力的话,可以自己开发数据源......
  • Linux中中括号{}应用与for循环的可迭代对象
     001、[root@pc1test]#foriinab8ab23ab98;doecho$i;done##直接迭代ab8ab23ab98[root@pc1test]#foriinab{8,23,98};doecho$i;done##可以写成如下形式ab8ab23ab98[root@pc1test]#foriinab{8,23yt,98};doecho$i;done......
  • 即构发布 | 移动端实时超分辨率技术,迭代视觉新体验
     超分辨率(SuperResolution,简称SR),是计算机视觉的一个经典应用。SR是指通过软件或硬件的方法,从观测到的低分辨率图像重建出相应的高分辨率图像,简单来说就是通过AI算法来放大原有图像的分辨率以达到提升画质的效果。在监控设备、卫星图像遥感、数字高清、显微成像、视频编码通......
  • UnrealSynth虚幻合成数据生成器
    UnrealSynth虚幻合成数据生成器利用虚幻引擎的实时渲染能力搭建逼真的三维场景,为YOLO等AI模型的训练提供自动生成的图像和标注数据。UnrealSynth生成的合成数据可用于深度学习模型的训练和验证,可以极大地提高各种行业细分场景中目标识别任务的实施效率,例如:安全帽检测、交通......