Python iter()函數(shù)用法實例分析
本文實例講述了Python iter()函數(shù)用法。分享給大家供大家參考,具體如下:
python中的迭代器用起來非常靈巧,不僅可以迭代序列,也可以迭代表現(xiàn)出序列行為的對象,例如字典的鍵、一個文件的行,等等。
迭代器就是有一個next()
方法的對象,而不是通過索引來計數(shù)。當(dāng)使用一個循環(huán)機制需要下一個項時,調(diào)用迭代器的next()方法,迭代完后引發(fā)一個StopIteration異常。
但是迭代器只能向后移動、不能回到開始、再次迭代只能創(chuàng)建另一個新的迭代對象。
反序迭代工具: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()函數(shù)的幫助信息:
>>> 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()
函數(shù)有兩種用法,一種是傳一個參數(shù),一種是傳兩個參數(shù)。結(jié)果都是返回一個iterator對象。
所謂的iterator對象,就是有個next()方法的對象。next方法的慣例或約定(convention)是,每執(zhí)行一次就返回下一個值(因此它要自己記錄狀態(tài),通常是在iterator對象上記錄),直到?jīng)]有值的時候raiseStopIteration。
傳1個參數(shù):參數(shù)collection應(yīng)是一個容器,支持迭代協(xié)議(即定義有__iter__()
函數(shù)),或者支持序列訪問協(xié)議(即定義有__getitem__()
函數(shù)),否則會返回TypeError異常。
傳2個參數(shù):當(dāng)?shù)诙€參數(shù)sentinel出現(xiàn)時,參數(shù)callable應(yīng)是一個可調(diào)用對象(實例),即定義了__call__()
方法,當(dāng)枚舉到的值等于哨兵時,就會拋出異常StopIteration。
>>> s='abc' #s支持序列訪問協(xié)議,它有__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 類支持迭代協(xié)議,因為它定義有__iter__()函數(shù) ... def __iter__(self): ... print '__iter__ is called!' ... self.result=[1,2,3] ... return iter(self.result) ... >>> t=test() # t支持迭代協(xié)議 >>> for i in t: #當(dāng)執(zhí)行for i in t 時,實際上是調(diào)用了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循環(huán)實際上是這樣工作的(for循環(huán)會自動調(diào)用迭代器的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: # 文件對象生成的迭代器會自動調(diào)用readline()方法,這樣循環(huán)遍歷就可以訪問文本文件的所有行 ... print line[:-1] ... love python hello python love python
上述for循環(huán)部分功能與以下代碼一致:
>>> 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
如果是傳遞兩個參數(shù)給 iter()
, 第一個參數(shù)必須是callable ,它會重復(fù)地調(diào)用第一個參數(shù),
直到迭代器的下個值等于sentinel:即在之后的迭代之中,迭代出來sentinel就立馬停止。
關(guān)于Python中,啥是可調(diào)用的,可以參考:python callable()函數(shù)
>>> class IT(object): def __init__(self): self.l=[1,2,3,4,5] self.i=iter(self.l) def __call__(self): #定義了__call__方法的類的實例是可調(diào)用的 item=next(self.i) print "__call__ is called,which would return",item return item def __iter__(self): #支持迭代協(xié)議(即定義有__iter__()函數(shù)) print "__iter__ is called!!" return iter(self.l) >>> it=IT() #it是可調(diào)用的 >>> 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
可以看到傳入兩個參數(shù)得到的it1的類型是一個callable_iterator,它每次在調(diào)用的時候,都會調(diào)用__call__
函數(shù),并且最后輸出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()函數(shù)傳兩個參數(shù)的功能而寫,如果真正想寫一個iterator的類,還需要定義next函數(shù),這個函數(shù)每次返回一個值就可以實現(xiàn)迭代了。
>>> 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的結(jié)束條件,不然就死循環(huán)了。
>>> 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
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python函數(shù)使用技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python字符串操作技巧匯總》、《Python入門與進階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對大家Python程序設(shè)計有所幫助。
相關(guān)文章
Python Pyqt5多線程更新UI代碼實例(防止界面卡死)
這篇文章通過代碼實例給大家介紹了Python Pyqt5多線程更新UI防止界面卡死的問題,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-12-12詳解python中g(shù)roupby函數(shù)通俗易懂
這篇文章主要介紹了詳解python中g(shù)roupby函數(shù)通俗易懂,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05對python中 math模塊下 atan 和 atan2的區(qū)別詳解
今天小編就為大家分享一篇對python中 math模塊下 atan 和 atan2的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01Django利用AJAX技術(shù)實現(xiàn)博文實時搜索
這篇文章主要介紹了Django如何利用AJAX技術(shù)實現(xiàn)博文實時搜索,幫助大家更好的理解和學(xué)習(xí)使用Django框架,感興趣的朋友可以了解下2021-05-05在Python中調(diào)用Ping命令,批量IP的方法
今天小編就為大家分享一篇在Python中調(diào)用Ping命令,批量IP的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01