Python Generators(產生器)——yield關鍵字

來源:互聯網
上載者:User
Python Generators(產生器)

產生器是這樣一個函數,它記住上一次返回時在函數體中的位置。對產生器函數的第二次(或第 n 次)調用跳轉至該函數中間,而上次調用的所有局部變數都保持不變。

產生器不僅“記住”了它資料狀態;產生器還“記住”了它在流量控制構造(在命令式編程中,這種構造不只是資料值)中的位置。

產生器的特點

     產生器是一個函數,而且函數的參數都會保留。

     迭代到下一次的調用時,所使用的參數都是第一次所保留下的,即是說,在整個所有函數調用的參數都是第一次所調用時保留的,而不是新建立的

在python中,yield就是這樣的一個產生器。

yield 產生器的運行機制:

當你問產生器要一個數時,產生器會執行,直至出現 yield 語句,產生器把 

     yield 的參數給你,之後產生器就不會往下繼續運行。 當你問他要下一個數時,他會從上次的狀態。開始運行,直至出現yield語句,把參數給你,之後停下。如此反覆
直至退出函數。(以上關於yield的描述,在後面列舉一個簡單的例子來解釋這段話)

yield的使用

在python中,當你定義一個函數,使用了yield關鍵字時,這個函數就是一個產生器,它的執行會和其他普通的函數有很多不同,函數返回的是一個對象,而不是你平常
所用return語句那樣,能得到結果值。如果想取得值,那得調用next()函數,如:

c = h() #h()包含了yield關鍵字#傳回值c.next()

每當調用一次迭代器的next函數,產生器函數運行到yield之處,返回yield後面的值且在這個地方暫停,所有的狀態都會被保持住,直到下次next函數被調用,或者碰到異常迴圈退出。

下面,來看看以下的例子代碼吧,是用來說明yield運行機制的。

def fib(max):    a, b = 1, 1    while a < max:        yield a #generators return an iterator that returns a stream of values.        a, b = b, a+b

程式運行:

for n in fib(15):    print n

從前面的運行機制描述中,可以獲知,程式運行到yield這行時,就不會繼續往下執行。而是返回一個包含當前函數所有參數的狀態的iterator對象。目的就是為了第二次被調用時,能夠訪問到函數所有的參數值都是第一次訪問時的值,而不是重新賦值。

程式第一次調用時:

def fib(max):    a, b = 1, 1    while a < max:        yield a #這時a,b值分別為1,1,當然,程式也在執行到這時,返回        a, b = b, a+b

程式第二次調用時:

從前面可知,第一次調用時,a,b=1,1,那麼,我們第二次調用時(其實就是調用第一次返回的iterator對象的next()方法),程式跳到yield語句處,

執行a,b = b, a+b語句,此時值變為:a,b = 1, (1+1) => a,b = 1, 2

程式繼續while迴圈,當然,再一次碰到了yield a 語句,也是像第一次那樣,儲存函數所有參數的狀態,返回一個包含這些參數狀態的iterator對象。

等待第三次的調用....

def fib(max):    a, b = 1, 1    while a < max:        yield a         a, b = b, a+b

通過上面的分析,可以一次類推的展示了yield的詳細運行過程了!

通過使用產生器的文法,可以免去寫迭代器類的繁瑣代碼,如,上面的例子使用迭代類來實現,代碼如下:

class Fib:    def __init__(self, max):        self.max = max    def __iter__(self):        self.a = 0        self.b = 1        return self    def next(self):        fib = self.a        if fib > self.max:            raise StopIteration        self.a, self.b = self.b, self.a + self.b        return fib

yield其他例子展示:排列,組合

#產生全排列    

def perm(items, n = None):    if n is None:        n = len(items)    for i in range(len(items)):        v = items[i:i+1]        if n==1:            yield v        else:            rest = items[:i] + items[i+1:]            for p in perm(rest, n-1):                yield v + pdef comb(items, n = None):    if n is None:        n = len(items)    else:        for i in range(len(items)):            v = items[i:i+1]            if 1 == n:                yield v            else:                rest = items[i+1:]                for c in comb(rest, n-1):                    yield v + c
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.