Python從入門到放棄之迭代器

迭代器是Python2.1中新加入的接口(PEP 234),說明以下:python

The iterator provides a 'get next value' operation that
produces the next item in the sequence each time it is called, raising an exception when no more items are available.

說到迭代器,就不得不提迭代器對象(Iterator)和可迭代對象(Iterable)。
接下來將分別介紹這兩種對象。python2.7

可迭代對象

可迭代對象(Iterable)能夠是任何對象,只要該對象擁有__iter__方法。該方法會返回一個迭代對象(Iterator)。
咱們經常使用到的如listtupledictsetstr等都是Iterableide

接下來用list作一些驗證。post

#!/usr/bin/env python2.7
"""以後全部代碼只保留必要部分"""
from collections import Iterator, Iterable

hasattr([], '__iter__')      # True
isinstance([], Iterable)     # True
type(iter([]))               # <type 'list_iterator'>

 注: iter()是內建方法,可將Iterable轉爲Iterator
iter()只接受Iterable對象做爲參數,若是不是則會拋出TypeError錯誤。code

能夠看出,list擁有__iter__方法, 它是一個可迭代對象,當對list使用iter()方法後,會返回一個Iterator對象。對象

a = [1, 2, 3, 4]
for i in a:
    print i

# 實際上內部執行
_iter = iter(a)
while True:
    try:
        a = _iter.next()
        print a
    except StopIteration:
        break

迭代器對象

迭代器對象則是在可迭代對象的基礎上多實現一個next()方法。接口

class Too(object):
    def __init__(self):
        self.n = 5

    def __iter__(self):
        return self

    def next(self):
        if self.n < 1:
            self.n = 5
            raise StopIteration
        val = self.n
        self.n -= 1
        return val

t = Too(5)

isinstance(t, Iterable)      # True
isinstance(t, Iterator)      # True

next(t)                      # 5
next(t)                      # 4
next(t)                      # 3
next(t)                      # 2
next(t)                      # 1
next(t)                      # StopIteration

如上則是實現一個簡單的迭代器。get

能夠看出,只有當使用next()方法時,迭代器纔會返回一個值,並且每次返回的都是與以前一次相對應的值,如第一次返回的是5,第二次返回的是4,而不是3或者2或者別的什麼數字。generator

這是由於迭代器內部有一種相似狀態機的機制,會保存每次的next()調用後的狀態,因此每次調用總會返回正確的結果。it

總結

迭代器對象與可迭代對象的關係總結起來就是一句話,迭代器對象必定是可迭代對象,可迭代對象不必定是迭代器對象。

參考文章:
StackOverflow
nvie.com
generators-uk

相關文章
相關標籤/搜索