在Python中,for循環可以用於Python中的任何類型,包括列表、元祖等等,實際上,for循環可用於任何“可迭代對象”,這其實就是迭代器
迭代器是一個實現了迭代器協議的對象,Python中的迭代器協議就是有next方法的對象會前進到下一結果,而在一系列結果的末尾是,則會引發 StopIteration。任何這類的對象在Python中都可以用for循環或其他遍歷工具迭代,迭代工具內部會在每次迭代時調用next方法,並且 捕捉StopIteration異常來確定何時離開。
迭代器的另一個優點就是它不要求你事先准備好整個迭代過程中所有的元素。迭代器僅僅在迭代至某個元素時才計算該元素,而在這之前或之後,元素可以不 存在或者被銷毀。這個特點使得它特別適合用於遍歷一些巨大的或是無限的集合,比如幾個G的文件,或是斐波那契數列等等。這個特點被稱為延遲計算或惰性求值 (Lazy evaluation)。
迭代器更大的功勞是提供了一個統一的訪問集合的接口。只要是實現了__iter__()方法的對象,就可以使用迭代器進行訪問。
使用內建的工廠函數iter(iterable)可以獲取迭代器對象:注意:迭代器是對象
lst = range(2) it = iter(lst) print it #輸出結果
<listiterator object at 0x00BB62F0>
使用迭代器的next()方法可以訪問下一個元素:
print it.next() 0
如何判斷迭代器還有更多的元素可以訪問呢?Python裡的迭代器並沒有提供類似has_next()這樣的方法。
那麼在這個例子中,我們如果訪問到了最後一個元素1後,再使用next()方法會怎樣呢?
it.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
Python遇到這樣的情況時將會拋出StopIteration異常。事實上,Python正是根據是否檢查到這個異常來決定是否停止迭代的。
這種做法與迭代前手動檢查是否越界相比各有優點。但Python的做法總有一些利用異常進行流程控制的嫌疑。
看到這個地方大家應該明白了迭代器的原理了吧,現在來說一說前面所說到的列表,元祖等可以迭代的原理了,還是要歸功於自帶的__iter__(前面和後面加上‘__’就是內置方法哦)
實例:
list1 = range(5) #生成一個list print '*****list1=', list1 #打印list1內容 print '*****type=', type(list1) #打印list類型 it = iter(list1) #講list1變成迭代器 print '*****type(iter)=', type(it) #打印生成後的對象類型 print '*****it=', it #打印it的信息 print '*****dir(list1)=', dir(list1) #查看列表方法
運行結果:
首先python對關鍵字in後的對象調用iter函數迭代器,然後調用迭代器的next方法獲得元素,直到拋出StopIteration異常。
事實上,因為迭代器如此普遍,python專門為for關鍵字做了迭代器的語法糖。在for循環中,Python將自動調用工廠函數iter()獲得迭代器,自動調用next()獲取元素,還完成了檢查StopIteration異常的工作。