導航:首頁 > 編程語言 > pythonyield遞歸

pythonyield遞歸

發布時間:2022-07-27 01:50:00

python遞歸生成器問題

如果調用 flatten3([[1,2],3])的話
for sublist in nested:
for element in fatten(sublist):
yield element

sublist分別為[1,2]和3
遞歸調用 fattern([1,2])返回一個包含1,2的子生成器,for element in fatten返回1,2用yield語句將1,2放入父生成器中,有了yield父生成器中才會有子生成器中的值
遞歸調用 flatten(3) TypeError執行yield 3,返回一個包含3的子生成器,yield element,3才會包含在父生成中

② 關於python的遞歸生成器

加了點注釋,自己看吧,下次不要用圖片了,直接拷貝代碼吧

#-*-coding:cp936-*-

defflatten(nested):
try:
#這里首先檢查nested是否可迭代,不可迭代則拋出TypeError
forsublistinnested:
#可迭代,那麼遞歸,檢查sublist是否還可以迭代
forelementinflatten(sublist):
#這里的element必定不可迭代,已經完全展開,因此使用yield輸出,返回上層
#如果sublist是不可迭代的,那麼flatten(sublist)返回的生成器就只有一個數據,就是sublist
#yieldelement也相當於yieldsublist
#否則的話,flatten(sublist)返回的是展開的數據
yieldelement
exceptTypeError:
#nested不可迭代,直接返回上層即可
yieldnested

③ Python生成器,遞歸時代碼執行順序

生成器就是用來生成有規律的值的
含有yield語句的函數就是生成器,counter(5)表示用參數start_at=5為初值調用生成
器,將函數對象賦值給count,count指向生成
器對象
每次調用生成器的next方法,就執行代碼到yield語句處返回yield後的值,因此第一次調用
執行到yield返回
,下次調用
next時從上次執行處接著執行到yield語句處,所以生成器中可以用while
True語句不用擔心死循環
yield這個表達式的值就是None,所以val一直是None

④ python遞歸生成器

defflattern(nested):
try:
iftype(nested)==type(""):
raiseTypeError()
forsublistinnested:
forelementinflattern(sublist):
yieldelement
exceptTypeError:
yieldnested
nested=[[1,2],[3,4],[5],6]
foriinflattern(nested):
printi

生成器的作用就是產生一個可迭代對象,可以在for這樣的語句中使用,yield element語句的作用就是將element添加到這個可迭代對象

def flattern(nested):
try:
for sublist in nested:
for element in flattern(sublist): #迭代flattern(子列表)所產生的生成器
yield element #對flattern的遞歸調用只是生成了新的生成器,得將這些生成器中的值添加到當前生成器
except TypeError:
yield nested #如果變數nested不可迭代,for語句會出現TypeError錯誤,這時將nested添加到當前生成器中

在try開頭加上了

if type(nested)==type(""):

raise TypeError()

因為字元是一直可以迭代的,如果不處理,如果參數中有字元串會無限遞歸下去

這個函數的作用就是將子列表完全擴展開產生一個生成器

⑤ python里yield的問題

'''
python中生成器是迭代器的一種,使用yield返回函數值。
每次調用yield會暫停,可以使用next()函數恢復生成器。

'''

deftest():
print('first')
yield1
print('second')
yield2
print('end')

r=test()
x=next(r)
print(x)

x=next(r)
print(x)

x=next(r)
print(x)

⑥ python的關鍵字yield有什麼作用

yield是python中定義為生成器函數,其本質是封裝了 __iter__和__next__方法 的迭代器;



與return返回的區別:return只能返回一次值,函數就終止了,而yield能多次返回值,每次返回都會將函數暫停,下一次next會從上一次暫停的位置繼續執行;



以下用示例說明:



deftest(a,b):
print("fromtest(),a+b=%d"%(a+b))
return("我是return返回的")

deftest_yield(a,b): #函數體中有yield關鍵字,函數就可以稱為生成器函數
print("fromtest_yield,a+b=%d"%(a+b))
yield("我是第一次碰到yield關鍵字返回的") #程序運行時碰到yield,退出函數體並記錄位置,下次調用跳過之前運行的代碼
print("fromtest_yield,a*2=%d"%(a*2))
yield("我是第二次調用碰到yield關鍵字返回的")

print(test(11,33))
g=test_yield(11,33)
print(next(g)) #通過next()調用生成器函數
print(next(g)) #第二次調用生成器函數


'''
執行結果:

fromtest(),a+b=44
我是return返回的
fromtest_yield,a+b=44
我是第一次碰到yield關鍵字返回的
fromtest_yield,a*2=22
我是第二次調用碰到yield關鍵字返回的

'''

⑦ python中return和yield怎麼用的兩個有什麼區別

常看到別人使用或討論yield語法,能搜到的中文解釋卻不多,今天決心搞定yield,把暫時的理解貼到這里.

搞定yield之前: 疊代器(iterator)

發現yield: 生成器(constructor)

使用yield: 遞歸調用

1. iterator

疊代器最簡單例子應該是數組下標了,且看下面的c++代碼:

int array[10];

for ( int i = 0; i < 10; i++ )

printf("%d ", array[i]);

疊代器工作在一個容器里(array[10]),它按一定順序(i++)從容器里取出值(array[i])並進行操作(printf("%d ", array[i])。

上面的代碼翻譯成python:

array = [i for i in range(10)]

for i in array:

print i,

for i in array幹了什麼(別亂想)?首先,array作為一個list是個容器,其次list這個內建類型有默認的next行為,python發現這些之後采 取的秘密的沒被各位看到的動作是:拿出array這丫容器的疊代器,從裡面next一下把值給i供for循環主體處置,for把這個值print了。

現在的問題是數據可以做容器疊代,代碼可以嗎?

怎麼不行,碗碟可以用來放菜,wk們不就聯想出用nt盛嗎,當然我們的yield不會那麼yellow + bt

2. constructor

怎麼把函數變成constructor? 在函數體里有yield就行了!

def gen():
print 'enter'
yield 1
print 'next'
yield 2
print 'next again'

for i in gen():
print i

各位!python看到gen函數里出現yield,知道可以用next了,問題是怎麼對代碼這個容器玩next?

從容器里拿到iterator的時候它還什麼也不是,處在容器入口處,對於數組來說就是下標為-1的地方,對於函數來說就是函數入口嘛事沒干,但是萬事俱備就欠next。

開始for i in g,next讓itreator爬行到yield語句存在的地方並返回值,

再次next就再爬到下一個yield語句存在的地方並返回值,依次這樣直到函數返回(容器盡頭)。
您一定看出來上面代碼的輸出是:

enter
1
next
2
next again

如果沒看出來請不要往下看了免得反被yield搞定。

3. 使用yield

yield的代碼疊代能力不但能打斷函數執行還能記下斷點處的數據,下次next書接上回,這正是遞歸函數需要的。

例如中序遍歷二叉樹:

(應該是David Mertz寫的)

def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x

for n in inorder(tree)

print n

當然yield這種代碼next的能力還可以用在其它方面,發現拍案的在貼咯。

⑧ 初學python,想問些關於yield等等的問題

關於yield,樓下kanchi240說的完全正確。我就不補充了。


想說的是。你這個用yield的函數的邏輯可能存在問題。入口參數nested是一個數組,函數里for sublist in nested被執行的時候,如果nested被改變就不合理,會產生一個異常,也許你設計的初衷就是如此。

defflatten(nested):
try:
forsublistinnested:
forelementinflatten(sublist):
yieldelement
exceptTypeError:
yieldnested
if__name__=="__main__":
forxinflatten(nested=[1,[2,[3]]]):
printx,type(x)

輸出結果是

1<type 'int'>

2<type 'int'>

3<type 'int'>

你這個好象又是遞歸函數。分解一下步驟是這樣子。

  1. flatten(nested=[1,[2,[3]]])

  2. sublist=1

  3. for element in flatten(sublist):此處在子調用異常,輸出1, 但是它被遞歸函數的循環再次yield。

  4. 下面依次類推。



我把程序修改了一下,可能看起來更清晰。

defflatten(nested,level=0):
try:
forsublistinnested:
print"sublist:",sublist,type(sublist)
forelementinflatten(sublist,level+1):
printlevel,"yield",element
yieldelement
exceptTypeError:
printlevel,'yieldtypeerror',nested,type(nested)
yieldnested
if__name__=="__main__":
forxinflatten(nested=[1,[2,[3]]]):
printx,type(x)

輸出結果是

sublist: 1 <type 'int'>
1 yield type error 1 <type 'int'>
0 yield 1
1 <type 'int'>
sublist: [2, [3]] <type 'list'>
sublist: 2 <type 'int'>
2 yield type error 2 <type 'int'>
1 yield 2
0 yield 2
2 <type 'int'>
sublist: [3] <type 'list'>
sublist: 3 <type 'int'>
3 yield type error 3 <type 'int'>
2 yield 3
1 yield 3
0 yield 3
3 <type 'int'>

閱讀全文

與pythonyield遞歸相關的資料

熱點內容
linuxpython綠色版 瀏覽:429
怎麼下載小愛同學音箱app 瀏覽:552
python佔位符作用 瀏覽:76
javajdbcpdf 瀏覽:541
php網頁模板下載 瀏覽:190
python試講課pygame 瀏覽:407
安居客的文件夾名稱 瀏覽:677
家裡伺服器如何玩 瀏覽:449
網站源碼使用視頻 瀏覽:746
stc89c52單片機最小系統 瀏覽:452
郵件安全證書加密 瀏覽:416
雲伺服器如何訪問百度 瀏覽:279
常州電信伺服器dns地址 瀏覽:839
用小方塊製作解壓方塊 瀏覽:42
圖像壓縮編碼實現 瀏覽:68
特色功能高拋低吸線副圖指標源碼 瀏覽:71
西方哲學史pdf羅素 瀏覽:874
python最常用模塊 瀏覽:184
溫州直播系統源碼 瀏覽:112
程序員在上海買房 瀏覽:384