1. 程式人生 > >python Iterator和Iterable

python Iterator和Iterable

Iterator是迭代器類,而Iterable是介面。
為什麼一定要實現Iterable介面,為什麼不直接實現Iterator介面呢?
看一下JDK中的集合類,比如List一族或者Set一族,都是實現了Iterable介面,但並不直接實現Iterator介面。
仔細想一下這麼做是有道理的。

  因為Iterator介面的核心方法next()或者hasNext() 是依賴於迭代器的當前迭代位置的。 
  如果Collection直接實現Iterator介面,勢必導致集合物件中包含當前迭代位置的資料(指標)。 
  當集合在不同方法間被傳遞時,由於當前迭代位置不可預置,那麼next()方法的結果會變成不可預知。 
  除非再為Iterator介面新增一個reset()方法,用來重置當前迭代位置。 
  但即時這樣,Collection也只能同時存在一個當前迭代位置。 
  而Iterable則不然,每次呼叫都會返回一個從頭開始計數的迭代器。 
  多個迭代器是互不干擾的。 

凡是可以for迴圈的,都是Iterable
凡是可以next()的,都是Iterator
Python中集合資料型別如list,truple,dict,str,都是Itrable不是Iterator,但可以通過iter()函式獲得一個Iterator物件

Python中的for迴圈就是通過next實現的
for x in [1,2,3,4,5]: pass
等價於:
先獲取iterator物件 it = iter([1,2,3,4,5]) while True: try: #獲取下一個值 x = next(it); except StopIteration: # 遇到StopIteration就退出迴圈 break

Python中 list,truple,str,dict這些都可以被迭代,但他們並不是迭代器。
因為和迭代器相比有一個很大的不同,list/truple/map/dict這些資料的大小是確定的,也就是說有多少是可知的。但迭代器不是,迭代器不知道要執行多少次,所以可以理解為不知道有多少個元素,每呼叫一次next(),就會往下走一步,是惰性的。
判斷是不是可以迭代,用Iterable
from collections import Iterable isinstance({}, Iterable) –> True isinstance((), Iterable) –> True isinstance(100, Iterable) –> False
判斷是不是迭代器,用Iterator
from collections import Iterator isinstance({}, Iterator) –> False isinstance((), Iterator) –> False isinstance( (x for x in range(10)), Iterator) –> True