迭代器(iterator)有時又稱游標(cursor)是程式設計的軟件設計模式,可在容器物件(container,例如鏈表或陣列)上遍訪的界面,設計人員無需關心容器物件的內存分配的實現細節。
摘自維基百科
也就是說迭代器類似於一個游標,卡到哪裡就是哪裡,可以通過這個來訪問某個可迭代對象的元素;同時,也不是只有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:
自己實現一個迭代器,如下(參見官網文檔):
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()
。是不是很省事。例如:
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()
,因為前者返回的是生成器,後者返回的是列表(列表消耗大量空間)。
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.
將可迭代對象轉化為迭代器。
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
零基礎如何入門Python http://www.linuxidc.com/Linux/2016-10/136485.htm
Ubuntu 14.04安裝Python 3.3.5 http://www.linuxidc.com/Linux/2014-05/101481.htm
CentOS上源碼安裝Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm
《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm
《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm
在CentOS 6.5上安裝Python2.7 http://www.linuxidc.com/Linux/2016-10/136206.htm
在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm