yield的功能類似于return,但是不同之處在于它返回的是生成器。
生成器
生成器是通過一個或多個yield表達式構成的函數,每一個生成器都是一個迭代器(但是迭代器不一定是生成器)。
如果一個函數包含yield關鍵字,這個函數就會變為一個生成器。
生成器并不會一次返回所有結果,而是每次遇到yield關鍵字后返回相應結果,并保留函數當前的運行狀態,等待下一次的調用。
由于生成器也是一個迭代器,那么它就應該支持next方法來獲取下一個值。
基本操作
# 通過`yield`來創建生成器def func(): for i in xrange(10); yield i
# 通過列表來創建生成器[i for i in xrange(10)]# 通過`yield`來創建生成器def func(): for i in xrange(10); yield i# 通過列表來創建生成器[i for i in xrange(10)]Python# 調用如下>>> f = func()>>> f # 此時生成器還沒有運行<generator object func at 0x7fe01a853820>>>> f.next() # 當i=0時,遇到yield關鍵字,直接返回>>> f.next() # 繼續上一次執行的位置,進入下一層循環...>>> f.next()>>> f.next() # 當執行完最后一次循環后,結束yield語句,生成StopIteration異常Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration>>># 調用如下>>> f = func()>>> f # 此時生成器還沒有運行<generator object func at 0x7fe01a853820>>>> f.next() # 當i=0時,遇到yield關鍵字,直接返回>>> f.next() # 繼續上一次執行的位置,進入下一層循環...>>> f.next()>>> f.next() # 當執行完最后一次循環后,結束yield語句,生成StopIteration異常Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration>>>
除了next函數,生成器還支持send函數。該函數可以向生成器傳遞參數。
>>> def func():... n = 0... while 1:... n = yield n #可以通過send函數向n賦值... >>> f = func()>>> f.next() # 默認情況下n為0>>> f.send(1) #n賦值1>>> f.send(2)>>> >>> def func():... n = 0... while 1:... n = yield n #可以通過send函數向n賦值... >>> f = func()>>> f.next() # 默認情況下n為0>>> f.send(1) #n賦值1>>> f.send(2)>>>
應用
最經典的例子,生成無限序列。
常規的解決方法是,生成一個滿足要求的很大的列表,這個列表需要保存在內存中,很明顯內存限制了這個問題。
def get_primes(start): for element in magical_infinite_range(start): if is_prime(element): return elementdef get_primes(start): for element in magical_infinite_range(start): if is_prime(element): return element
新聞熱點
疑難解答