十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章将为大家详细讲解有关Python中生成器与迭代器有什么区别,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
成都创新互联公司长期为近千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为潮南企业提供专业的成都做网站、网站设计,潮南网站改版等技术服务。拥有十余年丰富建站经验和众多成功案例,为您定制开发。Num01–>迭代器
对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()
函数。iter()
是python内置函数。
iter()
函数会返回一个定义了next()
方法的迭代器对象,它在容器中逐个访问容器内的元素。next()
也是python内置函数。在没有后续元素时,next()
会抛出一个StopIteration异常,通知for语句循环结束。
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()
函数的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法,Python2中是对象的next()
方法)。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。
1,迭代器协议:对象需要提供next()
方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。
2,可迭代对象:实现了迭代器协议对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter()
,把这些都变成Iterable(可迭代器对象)。
3,for item in Iterable 循环的本质就是先通过iter()
函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()
方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束
# 随便定义一个list listArray=[1,2,3] # 使用iter()函数 iterName=iter(listArray) print(iterName) # 结果如下:是一个列表list的迭代器 #print(next(iterName)) print(next(iterName)) print(next(iterName)) print(next(iterName))#没有迭代到下一个元素,直接抛出异常 # 1 # 2 # 3 # Traceback (most recent call last): # File "Test07.py", line 32, in # StopIteration
Python中一个实现了_iter_方法和_next_方法的类对象,就是迭代器,如下案例是计算菲波那切数列的案例
class Fib(object): def __init__(self, max): super(Fib, self).__init__() self.max = max def __iter__(self): self.a = 0 self.b = 1 return self def __next__(self): fib = self.a if fib > self.max: raise StopIteration self.a, self.b = self.b, self.a + self.b return fib # 定义一个main函数,循环遍历每一个菲波那切数 def main(): # 20以内的数 fib = Fib(20) for i in fib: print(i) # 测试 if __name__ == '__main__': main()
解释说明:
在本类的实现中,定义了一个_iter_(self)
方法,这个方法是在for循环遍历时被iter()调用,返回一个迭代器。因为在遍历的时候,是直接调用的python内置函数iter()
,由iter()通过调用_iter_(self)
获得对象的迭代器。有了迭代器,就可以逐个遍历元素了。而逐个遍历的时候,也是使用内置的next()函数通过调用对象的_next_(self)
方法对迭代器对象进行遍历。所以要实现_iter_(self)
和_next_(self)
这两个方法。
而且因为实现了_next_(self)
方法,所以在实现_iter_(self)
的时候,直接返回self就可以。
总结一句话就是:
在循环遍历自定义容器对象时,会使用python内置函数iter()
调用遍历对象的_iter_(self)
获得一个迭代器,之后再循环对这个迭代器使用next()
调用迭代器对象的_next_(self)
。
注意点: _iter_(self)
只会被调用一次,而_next_(self)
会被调用 n 次,直到出现StopIteration异常。
>延迟操作。也就是在需要的时候才产生结果,不是立即产生结果。
>生成器是只能遍历一次的。
>生成器是一类特殊的迭代器。
第一类:生成器函数:还是使用 def 定义函数,但是,使用yield而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。
如下案例加以说明:
# 菲波那切数列 def Fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return '亲!没有数据了...' # 调用方法,生成出10个数来 f=Fib(10) # 使用一个循环捕获最后return 返回的值,保存在异常StopIteration的value中 while True: try: x=next(f) print("f:",x) except StopIteration as e: print("生成器最后的返回值是:",e.value) break
第二类:生成器表达式:类似于列表推导,只不过是把一对大括号[]
变换为一对小括号()
。但是,生成器表达式是按需产生一个生成器结果对象,要想拿到每一个元素,就需要循环遍历。
如下案例加以说明:
# 一个列表 xiaoke=[2,3,4,5] # 生成器generator,类似于list,但是是把[]改为() gen=(a for a in xiaoke) for i in gen: print(i) #结果是: 2 3 4 5 # 为什么要使用生成器?因为效率。 # 使用生成器表达式取代列表推导式可以同时节省 cpu 和 内存(RAM)。 # 如果你构造一个列表(list)的目的仅仅是传递给别的函数, # 比如 传递给tuple()或者set(), 那就用生成器表达式替代吧! # 本案例是直接把列表转化为元组 kk=tuple(a for a in xiaoke) print(kk) #结果是: (2, 3, 4, 5) # python内置的一些函数,可以识别这是生成器表达式,外面有一对小括号,就是生成器 result1=sum(a for a in range(3)) print(result1) # 列表推导式 result2=sum([a for a in range(3)]) print(result2)
关于Python中生成器与迭代器有什么区别就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。