Python iter()函数用法实例分析
本文实例讲述了Pythoniter()函数用法。分享给大家供大家参考,具体如下:
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(mostrecentcalllast): File"",line1,in 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(mostrecentcalllast): File"",line1,in StopIteration
下面查看iter()函数的帮助信息:
>>>help(iter) Helponbuilt-infunctioniterinmodule__builtin__: iter(...) iter(collection)->iterator iter(callable,sentinel)->iterator Getaniteratorfromanobject.Inthefirstform,theargumentmust supplyitsowniterator,orbeasequence. Inthesecondform,thecallableiscalleduntilitreturnsthesentinel.
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__) Helponwrapper_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>>>iters1 >>>iters2 itersiters1iters2是同一个迭代器!! >>>iters.next() 'a' >>>iters.next() 'b' >>>iters.next() 'c' >>>iters.next() Traceback(mostrecentcalllast): File" ",line1,in StopIteration
>>>classtest:#test类支持迭代协议,因为它定义有__iter__()函数 ...def__iter__(self): ...print'__iter__iscalled!' ...self.result=[1,2,3] ...returniter(self.result) ... >>>t=test()#t支持迭代协议 >>>foriint:#当执行foriint时,实际上是调用了t.__iter__(),也就是__iter__(t),返回一个iterator对象 ...printi, ... __iter__iscalled! 123 >>>foriint.__iter__(): printi, __iter__iscalled!! 123 >>>foriintest.__iter__(t): printi, __iter__iscalled!! 123 >>>l=[1,2,3] >>>foriinl: ...printi, ... 123
#上述for循环实际上是这样工作的(for循环会自动调用迭代器的next()方法),如下: >>>iterl=iter(l) >>>whileTrue: ...try: ...i=iterl.next() ...exceptStopIteration: ...break ...printi, ... 123
>>>f=open(r'C:\Users\Administrator\Desktop\test.txt','w') >>>f.writelines(['lovepython\n','hellopython\n','lovepython\n']) >>>f.close() >>>f=open(r'C:\Users\Administrator\Desktop\test.txt','r') >>>forlineinf:#文件对象生成的迭代器会自动调用readline()方法,这样循环遍历就可以访问文本文件的所有行 ...printline[:-1] ... lovepython hellopython lovepython
上述for循环部分功能与以下代码一致:
>>>whileTrue: ...line=f.readline() ...ifline!='': ...printline[:-1] ...else: ...break ... lovepython hellopython lovepython
>>>f=open(r'C:\Users\91135\Desktop\test.txt','r') >>>f.readlines() ['lovepython\n','hellopython\n','\n','lovepython\n'] >>>f.seek(0) >>>f.next() 'lovepython\n' >>>f.next() 'hellopython\n' >>>f.next() '\n' >>>f.next() 'lovepython\n' >>>f.next() Traceback(mostrecentcalllast): File"",line1,in f.next() StopIteration >>>f.seek(0) >>>it1=iter(f) >>>it2=f.__iter__()
f iter1 iter2三者是同一个对象!!!
>>>f>>>it1 >>>it2 >>>f.next() 'lovepython\n' >>>it1.next() 'hellopython\n' >>>next(it2) '\n' >>>next(f) 'lovepython\n' >>>next(f) Traceback(mostrecentcalllast): File" ",line1,in next(f) StopIteration >>>it1.next() Traceback(mostrecentcalllast): File" ",line1,in it1.next() StopIteration >>>it2.next() Traceback(mostrecentcalllast): File" ",line1,in it2.next() StopIteration
iter(callable,sentinel)->iterator
如果是传递两个参数给iter(),第一个参数必须是callable,它会重复地调用第一个参数,
直到迭代器的下个值等于sentinel:即在之后的迭代之中,迭代出来sentinel就立马停止。
关于Python中,啥是可调用的,可以参考:pythoncallable()函数
>>>classIT(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__iscalled,whichwouldreturn",item returnitem def__iter__(self):#支持迭代协议(即定义有__iter__()函数) print"__iter__iscalled!!" returniter(self.l) >>>it=IT()#it是可调用的 >>>it1=iter(it,3)#it必须是callable的,否则无法返回callable_iterator >>>callable(it) True >>>it1>>>foriinit1: printi __call__iscalled,whichwouldreturn1 1 __call__iscalled,whichwouldreturn2 2 __call__iscalled,whichwouldreturn3
可以看到传入两个参数得到的it1的类型是一个callable_iterator,它每次在调用的时候,都会调用__call__函数,并且最后输出3就停止了。
>>>it2=iter(it) __iter__iscalled!! >>>it2>>>foriinit2: printi, 12345
与it1相比,it2就简单的多,it把自己类中一个容器的迭代器返回就可以了。
上面的例子只是为了介绍iter()函数传两个参数的功能而写,如果真正想写一个iterator的类,还需要定义next函数,这个函数每次返回一个值就可以实现迭代了。
>>>classNext(): def__init__(self,data=825): self.data=data def__iter__(self): returnself defnext(self): print"nextiscalled!!" ifself.data>828: raiseStopIteration else: self.data+=1 returnself.data >>>foriinNext(): printi nextiscalled!! 826 nextiscalled!! 827 nextiscalled!! 828 nextiscalled!! 829 nextiscalled!! >>>foriinNext(826): printi nextiscalled!! 827 nextiscalled!! 828 nextiscalled!! 829 nextiscalled!! >>>
唯一需要注意下的就是next中必须控制iterator的结束条件,不然就死循环了。
>>>it=Next() >>>it.__iter__() <__main__.Nextinstanceat0x02E75F80> >>>Next.__iter__(it) <__main__.Nextinstanceat0x02E75F80> >>>iter(it) <__main__.Nextinstanceat0x02E75F80> >>>it <__main__.Nextinstanceat0x02E75F80> >>>it=Next() >>>it.next() nextiscalled!! 826 >>>next(it) nextiscalled!! 827 >>>Next.next(it) nextiscalled!! 828 >>>next(it) nextiscalled!! 829 >>>it.next() nextiscalled!! Traceback(mostrecentcalllast): File"",line1,in it.next() File" ",line9,innext raiseStopIteration StopIteration
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python函数使用技巧总结》、《Python数据结构与算法教程》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。