python基礎教程(十一)

來源:互聯網
上載者:User

標籤:none   mil   elf   添加   close   not   throw   bre   世界   

 

迭代器

 

本節進行迭代器的討論。只討論一個特殊方法---- __iter__  ,這個方法是迭代器規則的基礎。

 

迭代器規則

迭代的意思是重複做一些事很多次---就像在迴圈中做的那樣。__iter__ 方法返回一個迭代器,所謂迭代器就是具有next方法的對象,在調用next方法時,迭代器會返回它的下一個值。如果next方法被調用,但迭代器沒有值可以返回,就會引發一個StopIteration異常。

 

這裡是一個婓波那契數例,使用迭代器如下:

class Fibs:    def __init__(self):        self.a = 0        self.b = 1    def next(self):        self.a , self.b = self.b , self.a + self.b        return self.a    def __iter__(self):        return self>>> fibs = Fibs() >>> for f in fibs:      if  f  > 1000:          print f          break    #因為設定了break ,所以迴圈在這裡停止。1597

內建函數iter可以從可迭代的對象中獲得迭代器。

>>> it = iter([1,2,3])>>> it.next()1>>> it.next()2

 

從迭代器得到序列

除了在迭代器和可迭代對象上進行迭代外,還能把它們轉換為序列。在大部分能使用序列的情況下,能使用迭代器替換。

class TestIterator:    value = 0    def next(self):        self.value += 1        if self.value > 10: raise StopIteration        return self.value    def __iter__(self):        return self>>> ti = TestIterator()>>> list(ti)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

 

 

 

產生器

 

產生器也叫 簡單產生器,產生器可以協助讀者寫出非常優雅的代碼,當然,編寫任何程式時不使用產生器也是可以的。

 

建立產生器

建立一個產生器就像建立函數一樣簡單。

>>> def flatten(nested):    for sublist in nested:        for element in sublist:            yield element            >>> nested = [[1,2],[3,4],[5]]#使用for迴圈>>> for num in flatten(nested):    print num    12345#或使用list函數>>> list(flatten(nested))[1, 2, 3, 4, 5]

 

遞迴產生器

上面建立的產生器只能處理兩層嵌套,為了處理嵌套使用了兩個for迴圈,如果要處理任意層的嵌套呢?例如,可以每層嵌套需要增加一個for迴圈,但不知道有幾層嵌套,所以必須把解決方案變得更靈活,現在可以用遞迴來解決。

>>> def fla(aa):    try:        for bb in aa:            for cc in fla(bb):                yield cc    except TypeError:        yield aa>>> list(fla([[[1],2],3,4,[5,[6,7]],8]))  #注意括弧層次比較多[1, 2, 3, 4, 5, 6, 7, 8]

  

當fla被調用時有兩種情況:基本情況和需要遞迴的情況

  在基本的情況中,函數被告知展開一個元素,這種情部下,for迴圈會引發一個TypeError 異常,產生會產生一個元素。

  如果展開的是一個列表,那麼就需要特殊情況處理。程式必須遍曆所有的子列表,並對它們調用fla。

-------------------

上面的做法有一個問題:如果aa 是一個類似於字串的對象(字串、Unicode、UserString等),那麼它就是一個序列,不會引發TypeError,但是你不想對這樣的對象進行迭代。

為了處理這種情況,則必須在產生器的開始處添加一個檢查語句。試著將傳入的對象和一個字串拼接,看看會不會出現TypeError,這是檢查一個對象是不是類似於字串最簡單快速的方法。

>>> def flatten(nested):    try:       #不要迭代類似字串的對象        try:nested + ‘‘        except TypeError: pass        else: raise TypeError        for sublist in nested:            for element in flatten(sublist):                yield element    except TypeError:        yield nested        >>> list(flatten([‘foo‘,[‘bar‘,[‘baz‘]]]))[‘foo‘, ‘bar‘, ‘baz‘]

如果nested+’’ 引發了一個TypError ,它就會被忽略。如果沒有引發TypeError,那麼內層try語句就會引發一個它自己的TypeError異常。

 

 

產生器方法

產生器新屬性是在開始運行後為產生器提供值的能力。表現為產生器和“外部世界”進行交流的渠道:

  * 外部範圍訪問產生器的send方法,就像訪問next 方法一樣,只不過前者使用一個參數(發送的“訊息”---任意對象)

  * 在內部則掛起產生器,yield現在作為運算式而不是語句使用,換句話說,當產生器重新啟動並執行時候,yield方法返回一個值,也就是外部通過send方法發送的值。如果next 方法被使用,那麼yield方法返回None. 

下面簡單的方例子來說明這種機制:

>>> def repeater(value):    while True:        new =(yield value)        if new is not None:value = new        >>> r = repeater(42)>>> r.next()42>>> r.send("hello, world!")‘hello, world!‘

產生器的另兩個方法:

  * throw方法(使用異常類型調用,還有可選的值以及回溯對象)用於在產生器內引發一個異常(在yield運算式中)

  * close 方法(調用時不用參數)用於停止產生器。

 

python基礎教程(十一)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.