c迭代器与生成器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c迭代器与生成器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4696字,纯文字阅读大概需要7分钟。
内容图文
![c迭代器与生成器](/upload/InfoBanner/zyjiaocheng/1053/710f1aa15c53479088a40759d327a5ca.jpg)
一:迭代器
1.什么是迭代?
1.重复 2.下一次重复是基于上一次的结果
# l=[‘a‘,‘b‘,‘c‘,‘d‘] # count=0 # while count < len(l): # print(l[count]) #count的值基于上一次结果,所以是迭代
# count+=1
2.迭代器协议
指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)。
迭代器的优点:
1.提供了一种不依赖索引的迭代方式
2.惰性计算,节省内存
迭代器的缺点:
1.取值不如按照索引取值的方便
2.只能前进,不能后退
3.无法获取长度
判断是否为可迭代对象或者迭代器对象的方法:
#
# from collections import Iterable,Iterator
#
# print(isinstance(g,Iterator)) #可判断是够为迭代器对象
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
#
def countdown(n):
#
print(‘starting countdown‘)
#
#
while n > 0:
#
yield n
#
n-=1
#
print(‘stop countdown‘)
#
g=countdown(5)
#
print(g.__next__())
#
print(g.__next__())
#
for i in g:
#
print(i)
3 迭代器
在介绍迭代器之前,我们先来了解一下容器这个概念。
容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取。简单来说,就好比一个盒子,我们可以往里面存放数据,也可以从里面一个一个地取出数据。在python中,属于容器类型地有:list,dict,set,str,tuple.....。容器仅仅只是用来存放数据的,我们平常看到的 l = [1,2,3,4]等等,好像我们可以直接从列表这个容器中取出元素,但事实上容器并不提供这种能力,而是可迭代对象赋予了容器这种能力。
说完了容器,我们在来谈谈迭代器。迭代器与可迭代对象区别在于:__next__()方法。
我们可以采用以下方法来验证一下:
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
from collections import Iterator f = open(‘a.txt‘) i = 1 s = ‘1234‘ d = {‘abc‘:1} t = (1, 2, 344) m = {1, 2, 34, } print(isinstance(i,Iterator)) print(isinstance(s,Iterator)) print(isinstance(d,Iterator)) print(isinstance(t,Iterator)) print(isinstance(m,Iterator)) print(isinstance(f,Iterator)) ########输出结果########## False False False False False True
结果显示:除了文件对象为迭代器,其余均不是迭代器
下面,我们进一步来验证一下:
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
print(hasattr(i,"__next__")) print(hasattr(s,"__next__")) print(hasattr(d,"__next__")) print(hasattr(t,"__next__")) print(hasattr(m,"__next__")) print(hasattr(f,"__next__")) #######结果########### False False False False False True
从输出结果可以表明,迭代器与可迭代对象仅仅就是__next__()方法的有无。
Tips:(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象,
然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代.
StopIteration异常:.__nex___执行后如果没有返回值就会报此异常。
Try 可检测异常:
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
l={‘a‘:1,‘x‘:2,‘w‘:3,‘z‘:4}
l=l.__iter__() #转换成迭代器while True:
try: #捕捉异常,检测其下缩进的语句是否有异常
i=l.__next__()
print(i)
except StopIteration: #except检测异常break
二:生成器(生成器的本质就是迭代器)
1.什么是生成器
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器是可迭代对象。
按照我们之前所说的,迭代器必须满足两个条件:既有__iter__(),又有__next__()方法。那么生成器是否也有这两个方法呢?答案是,YES。具体来通过以下代码来看看。
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
def func(): print( " one-------------> " ) yield 1 print( " two-------------> " ) yield 2 print( " three-----------> " ) yield 3 print( " four------------> " ) yield 4 print(hasattr(func(), ‘ __next__ ‘ )) print(hasattr(func(), ‘ __iter__ ‘ )) #########输出结果########### True True
Python有两种不同的方式提供生成器:
1.函数体内包含有yield关键字,该函数的执行结果是生成器(generator).但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行.
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
既然生成器就是迭代器,那么我们是不是也可以通过for循环来遍历出生成器中的内容呢?看下面代码.
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
def func(): print( " one-------------> " ) yield 1 print( " two-------------> " ) yield 2 print( " three-----------> " ) yield 3 print( " four------------> " ) yield 4 for i in func(): print(i) #########输出结果######## one-------------> 1 two-------------> 2 three-----------> 3 four------------> 4
很显然,生成器也可以通过for循环来遍历出其中的内容。
下面我们来看看生成器函数执行流程:
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
def func(): print( " one-------------> " ) yield 1 print( " two-------------> " ) yield 2 print( " three-----------> " ) yield 3 print( " four------------> " ) yield 4 g = func() # 生成器 == 迭代器 print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__())
每次调用g.__next__()就回去函数内部找yield关键字,如果找得到就输出yield后面的值并且返回;如果没有找到,就会报出异常。上述代码中如果在调用g.__next__()就会报错。Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
生成器就是迭代器,只能前进不能后退,我们看下这个例子:
![技术分享](/img/jia.gif)
![技术分享](/img/jian.gif)
#生成器函数补充 # def countdown(n): # while n > 0: # yield n # n-=1 # # g=countdown(5) # print(g.__next__()) # print(g.__next__()) # # print(‘=‘*20) # for i in g: # print(i) # # print(‘*‘*20) # for i in g: # print(i) =======结果======== 54 ==================== 321 ********************
yiled与return的区别:
原文:http://www.cnblogs.com/junxiansheng/p/7028084.html
内容总结
以上是互联网集市为您收集整理的c迭代器与生成器全部内容,希望文章能够帮你解决c迭代器与生成器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。