python range返回_迭代器 VS 生成器:Python告诉你!

最近有读者留言,问小编生成器与迭代器有什么区别,小编坦言玩了将近两年的python,还真没有直接用过生成器和迭代器的相关方法和协议,我也是恶补了两天,将我了解到的生成器和迭代器致使给大家讲一讲:

先说说迭代器(iterator),迭代器是访问可迭代对象的工具,是指用iter(obj)函数返回的对象(实例),并用next(it)函数获取可迭代对象的数据。关于迭代器函数iter,其语法为:it=iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是可迭代对象,而python数据类型都可以作为可迭代对象使用,此外range函数也是可迭代对象,而next(it)方法是指从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIterator错误,下面就是一个简单的迭代器函数iter示例:

615a0152b99b16a79cdce6864d931932.png

迭代器函数

可以发现,迭代器只能向前取值,不能后退,next方法使用一次,就代表指针向前进一,如果迭代器无法获取下一条记录,则会触发StopIterator错误,于是小编有个不成熟的想法,python的for循环是不是可以用迭代器+while模拟一下,因为for循环对象也是可迭代对象,但与迭代器不同的是,for循环越界时并不会报错,下面是相关代码:

a88ba740f25d4f729d4aa497fd4de91f.png

迭代器+while模拟for循环

因此for语句的本质可能就是while循环+迭代器,for语句里先从可迭代对象中返回一个迭代器,对迭代器执行next方法,如果触发StopIterator异常,迭代器则生成完毕,而代码中的print输出,在for循环里可以通过else语句体现,打印print("循环结束")。

下面解释一下什么是生成器,生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例),生成器主要有两种,一种是生成器函数,一种是生成器表达式。那什么是生成器函数呢?含有yield语句的函数就是生成器函数,此函数被调用将返回一个生成器对象,可以迭代器调用,可以直接使用next()方法,也可以for循环使用,代码如下:

5cce9cf4997d9641c5313c50a96c9e82.png

生成器函数

可以看出,生成器对象是一个可迭代对象,可以通过迭代器调用,也可以for循环使用,下面再举一个生成器例子,写一个生成器函数myeven(start, stop) ,此函数用来被生成从start开始到stop结束(不包含)区间内的一系列偶数,代码如下:

9fce86737553d5b939034f362d70517f.png

生成器示例-生成偶数

相信大家还记得range()函数吧,作为一个可迭代对象,可以和for循环配合生成随机数,而range()函数的本质可以模拟成一个生成器对象。前面已经说过,语法for i in range(num)输出i相当于迭代器的next函数,一直往前执行,找range()函数要i,执行到yield语句时,生成一个i,立即返回给i,这时继续找range()函数要i,继续执行i+=1,说白了,range()函数没有结束,而是两个循环一前一后相互执行,称之为协程,而当yield不能再提供i时,会触发一个StopIteration异常,结束执行!

那解释一下生成器的另外一种形式:生成器表达式。生成器对象 = ( 表达式 for 变量 in 可迭代对象 if 真值表达式) ,其中,if子句可以省略,相当于用推导式的形式创建一个新的生成器,生成器表达式和生成器函数一样,都是生成一个生成器对象,而括号只是一个生成器工具,是指有需要生成元素时,将for循环每生成的一个元素作为x传递给next(it),具体看代码:

0b2e0b61a7434b27a7bfca8df6706de9.png

生成器表达式

生成器的最大好处就在于用多少,生成多少,既保留了当前状态,下次又可在另外一个地方调用它,它会继续按以前状态继续执行下去,这对于数据量很大的程序有很大的用处。接着我们来看一个高级一点的,这里我们以产生斐波那契数列的前40个数为例,一般的方法都会产生大量的重复计算,生成的大量数据会占满内存,但是我们的生成器就可以完美解决这个问题。我们可以产生一个生成器,需要多少取多少即可,直接上代码:

f698813b3e64f0161d4e6fc7530de9fb.png

斐波那契数列

受制于水平的有限,这里将迭代器和生成器进行了简单的对比,而生成器的主要优势在于随用随时生成,不占用内存,尤其是在生成一个无穷数列的时候作用明显,不过小编想说,无论是用生成器生成数据,还是用递归或是其他方法,代码逻辑才是最重要的。需要交流和切磋的读者朋友,请在评论区积极留言,欢迎关注头条号:杜哥说python。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值