迭代器(iterator)有時又稱遊標(cursor)是程式設計的軟件設計模式,可在容器物件(container,例如鏈表或陣列)上遍訪的界面,設計人員無需關心容器物件的內存分配的實現細節。html
摘自維基百科python
也就是說迭代器相似於一個遊標,卡到哪裏就是哪裏,能夠經過這個來訪問某個可迭代對象的元素;同時,也不是隻有Python有這個特性。好比C++的STL中也有這個,如vector<int>::iterator it
。下面主要說一下Python中的可迭代對象和迭代器吧。設計模式
Python中常常使用for
來對某個對象進行遍歷,此時被遍歷的這個對象就是可迭代對象,像常見的list
,tuple
都是。若是給一個準確的定義的話,就是隻要它定義了能夠返回一個迭代器的__iter__
方法,或者定義了能夠支持下標索引的__getitem__
方法(這些雙下劃線方法會在其餘章節中全面解釋),那麼它就是一個可迭代對象。函數
迭代器是經過next()
來實現的,每調用一次他就會返回下一個元素,當沒有下一個元素的時候返回一個StopIteration
異常,因此實際上定義了這個方法的都算是迭代器。能夠用經過下面例子來體驗一下迭代器:工具
In [38]: s = 'ab' In [39]: it = iter(s) In [40]: it Out[40]: <iterator at 0x1068e6d50> In [41]: print it <iterator object at 0x1068e6d50> In [42]: it.next() Out[42]: 'a' In [43]: it.next() Out[43]: 'b' In [44]: it.next() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-44-54f0920595b2> in <module>() ----> 1 it.next() StopIteration:
本身實現一個迭代器,以下(參見官網文檔):oop
class Reverse: """Iterator for looping over a sequence backwards.""" def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def next(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index] rev = Reverse('spam') for char in rev: print char [output] m a p s
生成器是構造迭代器的最簡單有力的工具,與普通函數不一樣的只有在返回一個值的時候使用yield
來替代return
,而後yield
會自動構建好next()
和iter()
。是否是很省事。例如:ui
def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] >>> for char in reverse('golf'): ... print char ... f l o g
生成器最佳應用場景是:你不想同一時間將全部計算出來的大量結果集分配到內存當中,特別是結果集裏還包含循環。比方說,循環打印1000000個數,咱們通常會使用xrange()
而不是range()
,由於前者返回的是生成器,後者返回的是列表(列表消耗大量空間)。this
Help on built-in function range in module __builtin__: range(...) range(stop) -> list of integers range(start, stop[, step]) -> list of integers Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements. class xrange(object) | xrange(stop) -> xrange object | xrange(start, stop[, step]) -> xrange object | | Like range(), but instead of returning a list, returns an object that | generates the numbers in the range on demand. For looping, this is | slightly faster than range() and more memory efficient.
將可迭代對象轉化爲迭代器。spa
In [113]: s = 'abc' In [114]: s.next() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-114-5e5e6532ea26> in <module>() ----> 1 s.next() AttributeError: 'str' object has no attribute 'next' In [115]: it = iter(s) In [116]: it.next() Out[116]: 'a'
和列表推導式惟一的區別就是中括號換成了小括號,以下:設計
In [119]: num = (i for i in range(10)) In [120]: sum(num) Out[120]: 45