Python關鍵字yield詳解

劉志軍發表於2013-01-29

導讀:此文由伯樂線上 –劉志軍編譯自stackoverflow Python標籤中投票率最高的一個問題《The Python yield keyword explained》,e-satis 詳細回答了關於yield 以及 generator、iterable、iterator、iteration之間的關係。

迭代器(Iterator)

為了理解yield是什麼,首先要明白生成器(generator)是什麼,在講生成器之前先說說迭代器(iterator),當建立一個列表(list)時,你可以逐個的讀取每一項,這就叫做迭代(iteration)。

Mylist就是一個迭代器,不管是使用複雜的表示式列表,還是直接建立一個列表,都是可迭代的物件。

你可以使用“for··· in ···”來操作可迭代物件,如:list,string,files,這些迭代物件非常方便我們使用,因為你可以按照你的意願進行重複的讀取。但是你不得不預先儲存所有的元素在記憶體中,那些物件裡有很多元素時,並不是每一項都對你有用。

生成器(Generators)

生成器同樣是可迭代物件,但是你只能讀取一次,因為它並沒有把所有值存放記憶體中,它動態的生成值:

使用()和[]結果是一樣的,但是,第二次執行“ for in mygenerator”不會有任何結果返回,因為它只能使用一次。首先計算0,然後計算1,之後計算4,依次類推。

Yield

Yield是關鍵字, 用起來像return,yield在告訴程式,要求函式返回一個生成器。

這個示例本身沒什麼意義,但是它很清晰地說明函式將返回一組僅能讀一次的值,要想掌握yield,首先必須理解的是:當你呼叫生成器函式的時候,如上例中的createGenerator(),程式並不會執行函式體內的程式碼,它僅僅只是返回生成器物件,這種方式頗為微妙。函式體內的程式碼只有直到每次迴圈迭代(for)生成器的時候才會執行。

函式第一次執行時,它會從函式開始處直到碰到yield時,就返回迴圈的第一個值,然後,互動的執行、返回,直到沒有值返回為止。如果函式在執行但是並沒有遇到yield,就認為該生成器是空,原因可能是迴圈終止,或者沒有滿足任何”if/else”。

接下來讀一小段程式碼來理解生成器的優點:

控制生成器窮舉

對於訪問控制資源,生成器顯得非常有用。

迭代工具,你最好的朋友

迭代工具模組包含了操做指定的函式用於操作迭代器。想複製一個迭代器出來?連結兩個迭代器?以one liner(這裡的one-liner只需一行程式碼能搞定的任務)用內嵌的列表組合一組值?不使用list建立Map/Zip?···,你要做的就是 import itertools,舉個例子吧:

四匹馬賽跑到達終點排名的所有可能性:

理解迭代的內部機制:

迭代(iteration)就是對可迭代物件(iterables,實現了__iter__()方法)和迭代器(iterators,實現了__next__()方法)的一個操作過程。可迭代物件是任何可返回一個迭代器的物件,迭代器是應用在迭代物件中迭代的物件,換一種方式說的話就是:iterable物件的__iter__()方法可以返回iterator物件,iterator通過呼叫next()方法獲取其中的每一個值(譯者注),讀者可以結合Java API中的 Iterable介面和Iterator介面進行類比。

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

Python關鍵字yield詳解

相關文章