博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
迭代器(Iterable)和for..in..的三种协议
阅读量:6279 次
发布时间:2019-06-22

本文共 3159 字,大约阅读时间需要 10 分钟。

一。迭代器协议

  1.  迭代器协议:对象需要提供next方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代

  2. 可跌代对象:实现了迭代器协议的对象

  3. 协议是一种约定,可迭代对象实现迭代器协议,在Python中,迭代是通过for ... in来完成的

二。什么是可迭代对象

>>> from collections import Iterable>>> class Fib:...     def __iter__(self):...             pass... >>> a = Fib()>>> isinstance(a,Iterable)True>>>

  实现了__iter__方法的对象就是可迭代对象,a 就是可迭代对象。

三。什么是迭代器

>>> from collections import Iterable>>> class Fib1:...     def __init__(self):...         self.a = 0...     def next(self):...         self.a = self.a + 1...         if self.a > 4:...             raise StopIteration()...         return self.a... >>> class Fib:...     def __iter__(self):...         return Fib1()... >>> a = Fib()>>> b = iter(a)>>> b.next()1>>> b.next()2>>> b.next()3>>> b.next()4>>> b.next()Traceback (most recent call last):  File "
", line 1, in
File "
", line 7, in nextStopIteration>>>

  a是可迭代对象,通过 iter(a) 让解析器调用a的 __iter__ 方法返回一个迭代器让 b 接收,b 就是一个迭代器对象,所以说,迭代器就是实现了 next 方法的对象。

  整合一下上面例子可得

>>> a = Fib()>>> b = iter(a)>>> while True:...     try:...         b.next()...     except StopIteration:...         break... 1234>>>

  用循环调用 b 的 next 方法来迭代。

  再整合一下得

>>> a = Fib()>>> for x in a:...     print x... 1234>>>

  可见,for...in 就是这样迭代可迭代对象的。

四。简单迭代器

   以斐波那契数列为例,写一个简单的迭代器

>>> from collections import Iterable>>> class Fib:...     def __init__(self):...         self.a,self.b = 0,1...     def __iter__(self):...         return self...     def next(self):...         self.a,self.b = self.b,self.a + self.b...         if self.a > 100:...             raise StopIteration()...         return self.a... >>> a = Fib()>>> for n in a:...     print n... 1123581321345589>>> isinstance(a,Iterable)True>>>

    Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器对象(因为实现了next方法)

   再简化一下,不用for....in....

>>> a = Fib()>>> it = iter(a)                    // 解释器调用a的__iter__方法返回一个迭代器>>> next(it)                        // 调用it的next方法1>>> next(it)1>>> next(it)2>>> next(it)3>>>

  一个迭代器只迭代一次,重复跌代要获得新的迭代器。

五。for...in... 协议

   1.   协议A: __iter__ + next

       这是迭代器的协议,和上面说的一样,for..in.. 先调用iter(a) 让a的__iter__返回一个迭代器,然后循环这个迭代器的next方法直到没有下一个元素异常退出。

       for...in... 首先执行跌达器,比如存在跌达和__getitem__就会以跌达器遍历.

   2.  协议B: __getitem__

>>> class B:...     def __getitem__(self,n):...         print n...         time.sleep(2)...         return 'a'... >>> b = B()>>> for x in b:...     print x... 0a1a2a3a4

   n 一直循环的增长,直到有异常此循环才退出,一般作为下标索引遍历

>>> class B:...     def __init__(self):...         self.l = ['a','b','c','d','e']...     def __getitem__(self,n):...         return self.l[n]... >>> b = B()>>> for x in b:...     print x... abcde>>>

    3.  协议C: yield关键字

>>> def c():...     yield 'a'...     yield 'b'...     yield 'c'...     yield 'd'... >>> c1 = c()>>> print next(c1),next(c1),next(c1),next(c1),next(c1)a b c dTraceback (most recent call last):  File "
", line 1, in
StopIteration>>>

     用for..in来

>>> c1 = c()>>> for x in c1:...     print x... abcd>>>

    c1是生成器(generator),是可迭代对象,当然也是迭代器对象,不是一次性列出结果,用到了才按照某种规则得出结果,占用内存很少,用for...in...时不断循环调用 next() 方法,每次 next() 后 yield 返回一个值并挂起,到下次 next() 从上次挂起的 yield 接着执行,yield 和 return 一样返回值,生成器只迭代一次。

转载于:https://www.cnblogs.com/GH-123/p/7799617.html

你可能感兴趣的文章
腾讯云下安装 nodejs + 实现 Nginx 反向代理
查看>>
Javascript 中的 Array 操作
查看>>
java中包容易出现的错误及权限问题
查看>>
AngularJS之初级Route【一】(六)
查看>>
服务器硬件问题整理的一点总结
查看>>
SAP S/4HANA Cloud: Revolutionizing the Next Generation of Cloud ERP
查看>>
Mellanox公司计划利用系统芯片提升存储产品速度
查看>>
白帽子守护网络安全,高薪酬成大学生就业首选!
查看>>
ARM想将芯片装进人类大脑 降低能耗是一大挑战
查看>>
Oracle数据库的备份方法
查看>>
Selenium 自动登录考勤系统
查看>>
关于如何以编程的方式执行TestNG
查看>>
智能照明造福千家万户 家居智能不再是梦
查看>>
物联网如何跳出“看起来很美”?
查看>>
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.6 UDP回射客户程序:dg_cli函数...
查看>>
不要将时间浪费到编写完美代码上
查看>>
《第一桶金怎么赚——淘宝开店创业致富一册通》一一第1章 创业梦想,怎样起步...
查看>>