Python迭代器,可迭代對象,生成器

迭代器

迭代器(iterator)有時又稱遊標(cursor)是程式設計的軟件設計模式,可在容器物件(container,例如鏈表或陣列)上遍訪的界面,設計人員無需關心容器物件的內存分配的實現細節。html

摘自維基百科python

也就是說迭代器相似於一個遊標,卡到哪裏就是哪裏,能夠經過這個來訪問某個可迭代對象的元素;同時,也不是隻有Python有這個特性。好比C++的STL中也有這個,如vector<int>::iterator it。下面主要說一下Python中的可迭代對象和迭代器吧。設計模式

Python可迭代對象(Iterable)

Python中常常使用for來對某個對象進行遍歷,此時被遍歷的這個對象就是可迭代對象,像常見的list,tuple都是。若是給一個準確的定義的話,就是隻要它定義了能夠返回一個迭代器的__iter__方法,或者定義了能夠支持下標索引的__getitem__方法(這些雙下劃線方法會在其餘章節中全面解釋),那麼它就是一個可迭代對象。函數

Python迭代器(iterator)

迭代器是經過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

生成器(Generators)

生成器是構造迭代器的最簡單有力的工具,與普通函數不一樣的只有在返回一個值的時候使用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.

iter()

將可迭代對象轉化爲迭代器。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

參考

  1. Python官方文檔
  2. Python進階
相關文章
相關標籤/搜索