中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Python中的生成器和yield詳細介紹
來源:易賢網 閱讀:1130 次 日期:2015-01-16 14:48:04
溫馨提示:易賢網小編為您整理了“Python中的生成器和yield詳細介紹”,方便廣大網友查閱!

列表推導與生成器表達式

當我們創建了一個列表的時候,就創建了一個可以迭代的對象:

代碼如下:

>>> squares=[n*n for n in range(3)]

>>> for i in squares:

print i

0

1

4

這種創建列表的操作很常見,稱為列表推導。但是像列表這樣的迭代器,比如str、file等,雖然用起來很方便,但有一點,它們是儲存在內存中的,如果值很大,會很麻煩。

而生成器表達式不同,它執行的計算與列表包含相同,但會迭代的生成結果。它的語法與列表推導一樣,只是要用小括號來代替中括號:

代碼如下:

>>> squares=(n*n for n in range(3))

>>> for i in squares:

print i

0

1

4

生成器表達式不會創建序列形式的對象,不會把所有的值都讀取到內存中,而是會創建一個通過迭代并按照需求生成值的生成器對象(Generator)。

那么,還有沒有其它方法來產生生成器呢?

例子:斐波那契數列

例如有個需求,要生成斐波那契數列的前10位,我們可以這樣寫:

代碼如下:

def fib(n):

result=[]

a=1

b=1

result.append(a)

for i in range(n-1):

a,b=b,a+b

result.append(a)

return result

if __name__=='__main__':

print fib(10)

數字很少時,函數運行良好,但數字很多時,問題就來了,顯然生成一個幾千幾萬長度的列表并不是一個很好的主意。

這樣,需求就變成了:寫一個可以生成可迭代對象的函數,或者說,不要讓函數一次返回全部的值,而是一次返回一個值。

這好像與我們的常識相違背,當我們調用一個普通的Python函數時,一般是從函數的第一行代碼開始執行,結束于return語句、異?;蛘吆瘮到Y束(可以看作隱式的返回None):

代碼如下:

def fib(n):

a=1

b=1

for i in range(n-1):

a,b=b,a+b

return a

if __name__=='__main__':

print fib(10)

>>>

1 #返回第一個值時就卡住了

函數一旦將控制權交還給調用者,就意味著全部結束。函數中做的所有工作以及保存在局部變量中的數據都將丟失。再次調用這個函數時,一切都將從頭創建。函數只有一次返回結果的機會,因而必須一次返回所有的結果。通常我們都這么認為的。但是,如果它們并非如此呢?請看神奇的yield:

代碼如下:

def fib(n):

a=1

yield a

b=1

for i in range(n-1):

a,b=b,a+b

yield a

if __name__=='__main__':

for i in fib(10):

print i

>>>

1

1

2

3

5

8

13

21

34

生成器Generator

python中生成器的定義很簡單,使用了yield關鍵字的函數就可以稱之為生成器,它生成一個值的序列:

代碼如下:

def countdown(n):

while n>0:

yield n

n-=1

if __name__=='__main__':

for i in countdown(10):

print i

生成器函數返回生成器。要注意的是生成器就是一類特殊的迭代器。作為一個迭代器,生成器必須要定義一些方法,其中一個就是__next__()。如同迭代器一樣,我們可以使用next()函數(Python3是__next__() )來獲取下一個值:

代碼如下:

>>> c=countdown(10)

>>> c.next()

10

>>> c.next()

9

每當生成器被調用的時候,它會返回一個值給調用者。在生成器內部使用yield來完成這個動作。為了記住yield到底干了什么,最簡單的方法是把它當作專門給生成器函數用的特殊的return。調用next()時,生成器函數不斷的執行語句,直至遇到yield為止,此時生成器函數的”狀態”會被凍結,所有的變量的值會被保留下來,下一行要執行的代碼的位置也會被記錄,直到再次調用next()繼續執行yield之后的語句。

next()不能無限執行,當迭代結束時,會拋出StopIteration異常。迭代未結束時,如果你想結束生成器,可以使用close()方法。

代碼如下:

>>> c.next()

1

>>> c.next()

StopIteration

>>> c=countdown(10)

>>> c.next()

10

>>> c.close()

>>> c.next()

StopIteration

協程與yield表達式

yield語句還有更給力的功能,作為一個語句出現在賦值運算符的右邊,接受一個值,或同時生成一個值并接受一個值。

代碼如下:

def recv():

print 'Ready'

while True:

n=yield

print 'Go %s'%n

>>> c=recv()

>>> c.next()

Ready

>>> c.send(1)

Go 1

>>> c.send(2)

Go 2

以這種方式使用yield語句的函數稱為協程。在這個例子中,對于next()的初始調用是必不可少的,這樣協程才能執行可通向第一個yield表達式的語句。在這里協程會掛起,等待相關生成器對象send()方法給它發送一個值。傳遞給send()的值由協程中的yield表達式返回。

協程的運行一般是無限期的,使用方法close()可以顯式的關閉它。

如果yield表達式中提供了值,協程可以使用yield語句同時接收和發出返回值。

代碼如下:

def split_line():

print 'ready to split'

result=None

while True:

line=yield result

result=line.split()

>>> s=split_line()

>>> s.next()

ready to split

>>> s.send('1 2 3')

['1', '2', '3']

>>> s.send('a b c')

['a', 'b', 'c']

注意:理解這個例子中的先后順序非常重要。首個next()方法讓協程執行到yield result,這將返回result的值None。在接下來的send()調用中,接收到的值被放到line中并拆分到result中。send()方法的返回值就是下一條yield語句的值。也就是說,send()方法可以將一個值傳遞給yield表達式,但是其返回值來自下一個yield表達式,而不是接收send()傳遞的值的yield表達式。

如果你想用send()方法來開啟協程的執行,必須先send一個None值,因為這時候是沒有yield語句來接受值的,否則就會拋出異常。

代碼如下:

>>> s=split_line()

>>> s.send('1 2 3')

TypeError: can't send non-None value to a just-started generator

>>> s=split_line()

>>> s.send(None)

ready to split

使用生成器與協程

乍看之下,如何使用生成器和協程解決實際問題似乎并不明顯。但在解決系統、網絡和分布式計算方面的某些問題時,生成器和協程特別有用。實際上,yield已經成為Python最強大的關鍵字之一。

比如,要建立一個處理文件的管道:

代碼如下:

import os,sys

def default_next(func):

def start(*args,**kwargs):

f=func(*args,**kwargs)

f.next()

return f

return start

@default_next

def find_files(target):

topdir=yield

while True:

for path,dirname,filelist in os.walk(topdir):

for filename in filelist:

target.send(os.path.join(path,filename))

@default_next

def opener(target):

while True:

name=yield

f=open(name)

target.send(f)

@default_next

def catch(target):

while True:

f=yield

for line in f:

target.send(line)

@default_next

def printer():

while True:

line=yield

print line

然后將這些協程連接起來,就可以創建一個數據流處理管道了:

代碼如下:

finder=find_files(opener(catch(printer())))

finder.send(toppath)

程序的執行完全由將數據發送到第一個協程find_files()中來驅動,協程管道會永遠保持活動狀態,直到它顯式的調用close()。

總之,生成器的功能非常強大。協程可以用于實現某種形式的并發。在某些類型的應用程序中,可以用一個任務調度器和一些生成器或協程實現協作式用戶空間多線程,即greenlet。yield的威力將在協程,協同式多任務處理(cooperative multitasking),以及異步IO中得到真正的體現。

更多信息請查看IT技術專欄

更多信息請查看腳本欄目
易賢網手機網站地址:Python中的生成器和yield詳細介紹
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
国产女人精品视频| 亚洲精品免费网站| 亚洲国产日韩在线| 免费视频一区| 在线一区日本视频| 国产精品久久久久天堂| 久久精品免费观看| 91久久精品一区二区三区| 欧美日韩一区二区三区在线视频 | 亚洲视频在线观看免费| 欧美香蕉视频| 久久理论片午夜琪琪电影网| 亚洲精品乱码久久久久久按摩观| 国产精品高清网站| 麻豆久久久9性大片| 亚洲小说区图片区| 亚洲欧洲综合另类| 国产一区二区日韩精品欧美精品| 免费不卡在线视频| 午夜欧美电影在线观看| 亚洲精品一区二区三区不| 国产一区二区三区电影在线观看| 欧美久久一级| 裸体女人亚洲精品一区| 国产精品爽爽ⅴa在线观看| 亚洲制服av| 日韩视频免费大全中文字幕| 好看的亚洲午夜视频在线| 欧美三级午夜理伦三级中文幕| 久久蜜桃资源一区二区老牛| 午夜精品一区二区三区在线| 日韩一级大片在线| 亚洲高清视频一区二区| 国产一在线精品一区在线观看| 欧美日韩中字| 欧美国产91| 嫩模写真一区二区三区三州| 久久亚洲一区| 99热在这里有精品免费| 亚洲第一毛片| 欧美成人一区二区在线| 葵司免费一区二区三区四区五区| 日韩视频在线永久播放| 精东粉嫩av免费一区二区三区| 国产视频一区在线| 国产一区二区精品丝袜| 欧美日韩国产欧| 欧美 日韩 国产精品免费观看| 欧美一区二区在线视频| 亚洲午夜激情| 欧美有码视频| 国产在线视频欧美| 国产一区二区三区的电影| 国产拍揄自揄精品视频麻豆| 国产欧美欧洲在线观看| 国产丝袜美腿一区二区三区| 国产午夜精品久久久久久久| 国产午夜精品在线观看| 狠狠色噜噜狠狠狠狠色吗综合| 国产一区二区三区电影在线观看| 国产日韩欧美在线视频观看| 国产欧美日韩免费看aⅴ视频| 国产精品永久在线| 国产综合久久久久久鬼色| 国内精品嫩模av私拍在线观看 | 国产婷婷一区二区| 蜜臀av一级做a爰片久久| 欧美激情在线播放| 欧美性猛交视频| 国产亚洲一二三区| 依依成人综合视频| 亚洲免费激情| 欧美一区二区在线观看| 久久视频在线看| 欧美久久99| 国产日本欧美一区二区三区| 伊人久久亚洲美女图片| 99精品99久久久久久宅男| 亚洲免费视频观看| 久久另类ts人妖一区二区| 欧美日韩播放| 国内外成人免费激情在线视频网站 | 欧美成年人视频| 欧美日本乱大交xxxxx| 国产精品免费在线| 国产主播一区二区| 亚洲在线视频网站| 亚洲伦理久久| 欧美成年人网站| 影音先锋日韩有码| 久久亚洲国产精品一区二区| 国产日韩欧美亚洲| 欧美一区91| 亚洲在线播放电影| 欧美一区二区在线观看| 欧美午夜视频网站| 欧美天堂亚洲电影院在线观看| 国产精品乱人伦中文| 在线国产精品播放| 亚洲一区欧美二区| 免费在线一区二区| 黑人一区二区三区四区五区| 亚洲视频在线看| 欧美黄污视频| 影音先锋中文字幕一区二区| 午夜精品久久久久99热蜜桃导演| 欧美wwwwww| 国产在线欧美| 亚洲欧美一区二区三区久久| 欧美黄在线观看| 在线观看欧美日本| 久久大逼视频| 国产精品一区二区你懂得| 99热精品在线观看| 欧美激情欧美狂野欧美精品| 一色屋精品视频在线看| 欧美亚洲一区三区| 国产精品国产三级国产专区53| 国产午夜精品全部视频在线播放| 亚洲最新合集| 欧美日本亚洲| 99re在线精品| 欧美日韩亚洲91| 一本到高清视频免费精品| 欧美激情偷拍| 日韩系列在线| 国产精品r级在线| 亚洲免费影视| 国产欧美一区二区三区沐欲| 欧美一级视频免费在线观看| 国产精品丝袜xxxxxxx| 91久久精品国产| 欧美护士18xxxxhd| 亚洲精选视频在线| 欧美日韩亚洲天堂| 亚洲一区二区伦理| 国产精品揄拍一区二区| 欧美综合国产| 1000部精品久久久久久久久| 蜜桃av噜噜一区二区三区| 亚洲欧洲在线看| 欧美视频一区二区三区在线观看| 一区二区久久久久| 国产精自产拍久久久久久蜜| 久久人91精品久久久久久不卡| 亚洲欧美日韩精品久久亚洲区 | 免费久久99精品国产自| 亚洲小说欧美另类婷婷| 久久久夜夜夜| 国产精品嫩草99av在线| 国产日韩欧美综合一区| 欧美一区二区私人影院日本 | 国产精品嫩草99av在线| 宅男精品导航| 国产精品久久久久久久免费软件| 99精品视频免费观看| 国产精品久线观看视频| 新狼窝色av性久久久久久| 国产一区二区三区的电影| 久久永久免费| 99视频精品全部免费在线| 国产拍揄自揄精品视频麻豆| 蘑菇福利视频一区播放| 亚洲一区3d动漫同人无遮挡| 黄色精品一二区| 欧美日韩一区二区三区| 欧美一区二视频在线免费观看| 狠狠狠色丁香婷婷综合激情| 欧美日韩国产综合新一区| 欧美一区二区性| 亚洲精品日韩久久| 国产一区二区三区在线观看网站 | 国产美女一区| 欧美99久久| 欧美一区三区三区高中清蜜桃| 激情久久久久久久| 欧美色图五月天| 母乳一区在线观看| 欧美在线一二三区| 一本色道久久综合狠狠躁篇怎么玩 | 亚洲黄色影片| 国产目拍亚洲精品99久久精品 | 亚洲天天影视| 欧美日韩ab片| 日韩一二在线观看| 日韩一级视频免费观看在线| 国产精品久久久久久久午夜| 亚洲欧美国产不卡| 国产在线观看一区| 国产精品vvv| 欧美一区二区在线免费观看| 国产一级揄自揄精品视频| 欧美一区三区三区高中清蜜桃| 国产日韩精品电影| 欧美本精品男人aⅴ天堂| 欧美色网在线| 国产精品福利av| 欧美激情一区二区久久久| 久久久久国产精品一区| 欧美亚洲视频|