[英]Python Generator
def countDown(i):
if i<> 0:
For j in countDown( i - 1 ):
yield j
yield i
if __name__ == '__main__':
for k in countDown(5):
print k
if k == 6 : break
在調試此代碼時,執行路徑與我預期的有所不同。 我的期望:countDown中的“ for”循環將遞歸調用該函數:countDown(4),countDown(3),countDown(2)以及countDown(1)和countDown(0)。 此時,如果不滿足條件,則開始“返回階段”,將執行Yield j。 這會將控件返回到“ main”函數中的for循環。
此for循環的下一次迭代再次調用countDown(5),該計數從最后一個Yield-Yield j開始。 這將執行for ... countdown(i-1)循環,並調用countDown(4),countDown(3),CountDown(2).. countDown(0)。 然后,“返回階段”開始並達到第一個Yield j(現在j從較早的第一遍開始遞增)。 這將使控制返回到“ main”函數中的for循環。
在調試時,這是我發現的內容:
1)如果i <> 0失敗(如遞歸末尾所述),則似乎執行Yield i。 然后似乎在控制權返回到k ... main之前彈出堆棧中的每個countDown。
2)在第二次迭代中,對於g中的k,堆棧進入返回階段-堆棧的頂部到底部是countDown(1),countDown(2),countDown(3),countDown(4),然后開始“返回階段”。 在該階段,j的值為“ 1”。 所以。 在開始返回階段之前,為什么它不會下降到countDown(0),其中i = 1?
誰能解釋這應該如何工作-遞歸和Generator函數的組合? 很抱歉,漫長的大風過后-沒有其他方法可以解釋它
謝謝。 伙計們的答復。
我到目前為止的理解:
1)在countDown(5)中k的第一次迭代:入口
功能說明
======== ===========
countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
countDown(0)中j的countDown(1)
countDown(0)如果語句失敗,則不返回任何內容
返回階段
一種)
countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
CountDown(0)中j的CountDown(1)=無-因為countDown(0)不返回任何內容(因為如果條件失敗),j沒有任何結果,因此不會屈服j(收益j在For循環內) 。 但是,收益率我被執行了,我這里是1。 因此,countdown(1)將1返回上一個遞歸。
b)countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)= 1中j的countDown(2)現在j的值為'1'。 因此,countdown(1)中的For j為true。 因此,它計算出Yield j =1。結果countDown(2)返回1。這是j分配給i的地方。
c)countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)= 1中j的countDown(3)現在j的值為'1'。 因此,countdown(2)中的For j為true。 因此,它將得出Yield j =1。結果countDown(3)返回1
...
e)countDown(4)= 1中j的Countdown(5)由count Down(4)返回的值為1。 因此,j為1。因此,執行了countDown(4)中的for j。
The next statement Yield j within the For statement gets exceuted.
it returns 1.
對於countDow(5)中的k,k將得到1。這將被打印出來。
2)現在到countDown(5)中for k的第二次迭代
遞歸“條目”
=================
在countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3),其中j = 1
在countDown(1)中j的countdown(2),其中j = 1
countdown(1)執行Yield i,因為上一次迭代步驟a)yield是最后執行的語句
a)countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3),其中j = 1
countDown(1)中j的countdown(2),其中j = 1 Countdown(1)返回值1,j已經具有值1,因此,它執行下一步,即產生產量i,其中i =2。countDown( 2)返回收益率i = 2
b)countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3)
因為countDown(2)返回2,所以j得到這個新值j = 2產生j得到執行c)
在countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
countDown(3)中j的countdown(4),其中j = 1,因為countdown(3)返回值2,如b)所示,j的新值為2
...
e)countDown(4)中j的countdown(5)變為2
也許這可以闡明看漲/收益的發生順序:
編輯:
def countDown(i):
if i<> 0:
for j in countDown( i - 1 ):
yield 'inner : ' + str(j)
yield 'outer : ' + str(i)
>>> for k in countDown(5): print k
...
inner : inner : inner : inner : outer : 1
inner : inner : inner : outer : 2
inner : inner : outer : 3
inner : outer : 4
outer : 5
它一直推到i為0,這不會產生任何結果,因此countDown(1)中的for循環也不會。 接下來,countDown(1)產生1,該計數返回由countDown(2),countDown(3),countDown(4)和countDown(5)產生。 換句話說,產生的值將返回到前一個調用方,在此之前,它將被一次又一次地產生,直到取消調用堆棧。 下一個要用盡的生成器是countDown(2),它產生2到countDown(3),countDown(4)和countDown(5)。 生成器連續排放,直到最后countDown(5)產生5。
假設您遍歷countDown(5)
:
countDown(5)
獲取下一個countDown(4)
countDown(4)
獲取下一個countDown(3)
countDown(3)
獲取下一個countDown(2)
countDown(2)
獲取下一個countDown(1)
countDown(1)
獲取下一個countDown(0)
countDown(0)
yield i
= 0, countDown(0)
停止 countDown(1)
yield j
= 0 countDown(2)
yield j
= 0 countDown(3)
yield j
= 0 countDown(4)
yield j
= 0 countDown(5)
yield j
= 0 countDown(5)
獲取下一個countDown(4)
countDown(4)
獲取下一個countDown(3)
countDown(3)
獲取下一個countDown(2)
countDown(2)
獲取下一個countDown(1)
countDown(1)
yield i
= 1, countDown(1)
stop countDown(2)
yield j
= 1 countDown(3)
yield j
= 1 countDown(4)
yield j
= 1 countDown(5)
yield j
= 1 countDown(5)
獲取下一個countDown(4)
countDown(4)
獲取下一個countDown(3)
countDown(3)
獲取下一個countDown(2)
countDown(2)
yield i
= 2, countDown(2)
停止 countDown(3)
yield j
= 2 countDown(4)
yield j
= 2 countDown(5)
yield j
= 2 countDown(5)
獲取下一個countDown(4)
countDown(4)
獲取下一個countDown(3)
countDown(3)
yield i
= 3, countDown(3)
停止 countDown(4)
yield j
= 3 countDown(5)
yield j
= 3 countDown(5)
獲取下一個countDown(4)
countDown(4)
yield i
= 4, countDown(4)
停止 countDown(5)
yield j
= 4 countDown(5)
yield i
= 5, countDown(5)
停止 不知道為什么我無法編輯您的帖子。
def countDown(i):
if i <> 0:
For j in countDown( i - 1 ):
yield j
yield i
看來您只想倒數,所以yield i
。 然后您將得到4 3 2 1 0
而不是0 1 2 3 4
def countDown(i):
yield i
if i <> 0:
For j in countDown( i - 1 ):
yield j
謝謝。 伙計們的答復。
經過進一步調試:
1)第一次迭代-對於countDown(5)中的k:
遞歸進入階段
功能說明
======== ===========
countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
countDown(0)中j的countDown(1)
countDown(0)如果語句失敗,則不返回任何內容
遞歸返回階段
一種)
countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
CountDown(0)中j的CountDown(1)=無-因為countDown(0)不返回任何內容(因為如果條件失敗),j沒有任何結果,因此不會屈服j(收益j在For循環內) 。 但是,收益率我被執行了,我這里是1。 因此,countdown(1)將1返回上一個遞歸。
b)countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)中j的countDown(3)
countDown(1)= 1中j的countDown(2)現在j的值為'1'。 因此,countdown(1)中的For j為true。 因此,它計算出Yield j =1。結果countDown(2)返回1。這是j分配給i的地方。
c)countDown(4)中j的countdown(5)
countDown(3)中j的countdown(4)
countDown(2)= 1中j的countDown(3)現在j的值為'1'。 因此,countdown(2)中的For j為true。 因此,它將得出Yield j =1。結果countDown(3)返回1
...
e)countDown(4)= 1中j的Countdown(5)由count Down(4)返回的值為1。 因此,j為1。因此,執行了countDown(4)中的for j。
The next statement Yield j within the For statement gets exceuted.
it returns 1.
對於countDow(5)中的k,k將得到1。這將被打印出來。
2)現在到第二次迭代-對於countDown(5)中的k
遞歸進入階段
在countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3),其中j = 1
在countDown(1)中j的countdown(2),其中j = 1
countdown(1)執行Yield i,因為上一次迭代步驟a)yield是最后執行的語句
遞歸返回
a)countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3),其中j = 1
countDown(1)中j的countdown(2),其中j = 1 Countdown(1)返回值1,j已經具有值1,因此,它執行下一步,即產生產量i,其中i =2。countDown( 2)返回收益率i = 2
b)countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
在countDown(3)中j的countdown(4),其中j = 1
countDown(2)中j的countDown(3)
因為countDown(2)返回2,所以j得到這個新值j = 2產生j得到執行c)
在countDown(4)中j的countdown(5),其中j = 1(Y是最后執行的語句)
countDown(3)中j的countdown(4),其中j = 1,因為countdown(3)返回值2,如b)所示,j的新值為2
...
e)countDown(4)中j的countdown(5)變為2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.