[转载] python iter( )函数

参考链接: Python iter()

python中的迭代器用起来非常灵巧,不仅可以迭代序列,也可以迭代表现出序列行为的对象,例如字典的键、一个文件的行,等等。 

迭代器就是有一个next()方法的对象,而不是通过索引来计数。当使用一个循环机制需要下一个项时,调用迭代器的next()方法,迭代完后引发一个StopIteration异常。 但是迭代器只能向后移动、不能回到开始、再次迭代只能创建另一个新的迭代对象。 反序迭代工具:reversed()将返回一个反序访问的迭代器。python中提供的迭代模块:itertools模块  

先看几个例子: 

>>> l=[2,3,4] >>> iterl=iter(l) >>> iterl.next() 2 >>> iterl.next() 3 >>> iterl.next() 4 >>> iterl.next() Traceback (most recent call last):   File "<stdin>", line 1, in <module> StopIteration  

  

>>> d={'one':1,'two':2,'three':3} >>> d {'three': 3, 'two': 2, 'one': 1} >>> iterd=iter(d) #字典的迭代器会遍历字典的键(key) >>> iterd.next() 'three' >>> iterd.next() 'two' >>> iterd.next() 'one' >>> iterd.next() Traceback (most recent call last):   File "<stdin>", line 1, in <module> StopIteration  

  

下面查看iter()函数的帮助信息: 

>>> help(iter) 

Help on built-in function iter in module __builtin__:   iter(...)     iter(collection) -> iterator     iter(callable, sentinel) -> iterator          Get an iterator from an object.  In the first form, the argument must     supply its own iterator, or be a sequence.     In the second form, the callable is called until it returns the sentinel.  

iter()函数有两种用法,一种是传一个参数,一种是传两个参数。结果都是返回一个iterator对象。 

所谓的iterator对象,就是有个next()方法的对象。next方法的惯例或约定(convention)是,每执行一次就返回下一个值(因此它要自己记录状态,通常是在iterator对象上记录),直到没有值的时候raiseStopIteration。 

传1个参数:参数collection应是一个容器,支持迭代协议(即定义有__iter__()函数),或者支持序列访问协议(即定义有__getitem__()函数),否则会返回TypeError异常。 

传2个参数:当第二个参数sentinel出现时,参数callable应是一个可调用对象(实例),即定义了__call__()方法,当枚举到的值等于哨兵时,就会抛出异常StopIteration。 

>>> s='abc'  #s支持序列访问协议,它有__getitem__()方法  

>>> help(str.__getitem__) Help on wrapper_descriptor:   __getitem__(...)     x.__getitem__(y) <==> x[y] 

>>> s.__getitem__(1) 'b' >>> s[1] 'b' 

 >>> iters=iter(s) #iters是一个iterator对象,它有next()和__iter__()方法 >>> iters1=iters.__iter__() >>> iters2=iter(iters) >>> iters <iterator object at 0x030612D0> >>> iters1 <iterator object at 0x030612D0> >>> iters2 <iterator object at 0x030612D0> 

iters  iters1   iters2 是同一个迭代器!! >>> iters.next() 'a' >>> iters.next() 'b' >>> iters.next() 'c' >>> iters.next() Traceback (most recent call last):   File "<stdin>", line 1, in <module> StopIteration 

  

>>> class test:  # test 类支持迭代协议,因为它定义有__iter__()函数 ...     def __iter__(self): ...         print '__iter__ is called!' ...         self.result=[1,2,3] ...         return iter(self.result) ...  >>> t=test()  # t支持迭代协议 

>>> for i in t:   #当执行for i in t 时,实际上是调用了t.__iter__(),也就是__iter__(t),返回一个iterator对象 ...     print i, ...  __iter__ is called! 1 2 3  

>>> for i in t.__iter__():                 print i,  __iter__ is called!! 1 2 3 >>> for i in test.__iter__(t):                 print i,  __iter__ is called!! 1 2 3  

  

>>> l=[1,2,3] >>> for i in l: ...     print i, ...  1 2 3  

#上述for循环实际上是这样工作的(for循环会自动调用迭代器的next()方法),如下:  

>>> iterl=iter(l) >>> while True: ...     try: ...         i=iterl.next() ...     except StopIteration: ...         break ...     print i, ...  1 2 3  

  

  

>>> f=open(r'C:\Users\Administrator\Desktop\test.txt','w') >>> f.writelines(['love python\n','hello python\n','love python\n']) >>> f.close() >>> f=open(r'C:\Users\Administrator\Desktop\test.txt','r') >>> for line in f:  # 文件对象生成的迭代器会自动调用readline()方法,这样循环遍历就可以访问文本文件的所有行 ...     print line[:-1] ...  love python hello python love python  

上述for循环部分功能与以下代码一致: 

>>> while True: ...     line=f.readline() ...     if line!='': ...         print line[:-1] ...     else: ...         break ...  love python hello python love python  

  

>>> f=open(r'C:\Users\91135\Desktop\test.txt','r') >>> f.readlines() ['love python\n', 'hello python\n', '\n', 'love python\n'] >>> f.seek(0) >>> f.next() 'love python\n' >>> f.next() 'hello python\n' >>> f.next() '\n' >>> f.next() 'love python\n' >>> f.next() Traceback (most recent call last):   File "<pyshell#140>", line 1, in <module>     f.next() StopIteration >>> f.seek(0) >>> it1=iter(f) >>> it2=f.__iter__() 

f    iter1    iter2 三者是同一个对象!!! >>> f <open file 'C:\\Users\\91135\\Desktop\\test.txt', mode 'r' at 0x030E9A70> >>> it1 <open file 'C:\\Users\\91135\\Desktop\\test.txt', mode 'r' at 0x030E9A70> >>> it2 <open file 'C:\\Users\\91135\\Desktop\\test.txt', mode 'r' at 0x030E9A70> >>> f.next() 'love python\n' >>> it1.next() 'hello python\n' >>> next(it2) '\n' >>> next(f) 'love python\n' >>> next(f) Traceback (most recent call last):   File "<pyshell#247>", line 1, in <module>     next(f) StopIteration >>> it1.next() Traceback (most recent call last):   File "<pyshell#248>", line 1, in <module>     it1.next() StopIteration >>> it2.next() Traceback (most recent call last):   File "<pyshell#249>", line 1, in <module>     it2.next() StopIteration  

  

iter(callable, sentinel) -> iterator 如果是传递两个参数给 iter() , 第一个参数必须是callable ,它会重复地调用第一个参数,  直到迭代器的下个值等于sentinel:即在之后的迭代之中,迭代出来sentinel就立马停止。 关于Python中,啥是可调用的,可以参考:python callable()函数 >>> class IT(object):         def __init__(self):                self.l=[1,2,3,4,5]                self.i=iter(self.l)         def __call__(self):   #定义了__call__方法的类的实例是可调用的                item=next(self.i)                print "__call__ is called,which would return",item                return item         def __iter__(self): #支持迭代协议(即定义有__iter__()函数)                print "__iter__ is called!!"                return iter(self.l)  >>> it=IT() #it是可调用的 >>> it1=iter(it,3) #it必须是callable的,否则无法返回callable_iterator >>> callable(it) True >>> it1 <callable-iterator object at 0x0306DD90> >>> for i in it1: print i  __call__ is called,which would return 1 1 __call__ is called,which would return 2 2 __call__ is called,which would return 3  可以看到传入两个参数得到的it1的类型是一个callable_iterator,它每次在调用的时候,都会调用__call__函数,并且最后输出3就停止了。 >>> it2=iter(it) __iter__ is called!! >>> it2 <listiterator object at 0x030A1FD0> >>> for i in it2: print i,   1 2 3 4 5   与it1相比,it2就简单的多,it把自己类中一个容器的迭代器返回就可以了。   上面的例子只是为了介绍iter()函数传两个参数的功能而写,如果真正想写一个iterator的类,还需要定义next函数,这个函数每次返回一个值就可以实现迭代了。 >>> class Next():                 def __init__(self,data=825):                            self.data=data                 def __iter__(self):                            return self                def next(self):                            print "next is called!!"                            if self.data>828:                                    raise StopIteration                            else:                                    self.data+=1                                    return self.data  >>> for i in Next(): print i   next is called!! 826 next is called!! 827 next is called!! 828 next is called!! 829 next is called!! >>> for i in Next(826): print i   next is called!! 827 next is called!! 828 next is called!! 829 next is called!! >>>  唯一需要注意下的就是next中必须控制iterator的结束条件,不然就死循环了。  

>>> it=Next() >>> it.__iter__() <__main__.Next instance at 0x02E75F80> >>> Next.__iter__(it) <__main__.Next instance at 0x02E75F80> >>> iter(it) <__main__.Next instance at 0x02E75F80> >>> it <__main__.Next instance at 0x02E75F80>  

  

>>> it=Next() >>> it.next() next is called!! 826 >>> next(it) next is called!! 827 >>> Next.next(it) next is called!! 828 >>> next(it) next is called!! 829 >>> it.next() next is called!!  Traceback (most recent call last):   File "<pyshell#68>", line 1, in <module>     it.next()   File "<pyshell#1>", line 9, in next     raise StopIteration StopIteration  

(完)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值