答案 0 :(得分: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)next产生1,它返回由countDown(2),countDown(3),countDown(4)和countDown(5)产生。换句话说,产生的值返回到前一个调用者,在那里它一次又一次地产生,直到调用栈被展开。要耗尽的下一个生成器是countDown(2),它返回countDown(3),countDown(4)和countDown(5)。发电机连续耗尽,直到最后countDown(5)产生5。
答案 1 :(得分:1)
假设你迭代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)
停止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
答案 2 :(得分:0)
THX。伙计们回复。
进一步调试后:
1)第一次迭代 - 对于countDown(5)中的k:
递归录入阶段
功能说明
======== ===========
countDown(4)中j的倒计时(5)
countDown(3)中j的倒计时(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
countDown(0)中j的countDown(1)
countDown(0)如果语句失败并且不返回任何内容
递归返回阶段
a)
countDown(4)中j的倒计时(5)
countDown(3)中j的倒计时(4)
countDown(2)中j的countDown(3)
countDown(1)中j的countDown(2)
countDown(0)中的j的CountDown(1)=无 - 因为countDown(0)什么都不返回 (因为如果条件失败),j没有任何东西,因此产生j, 不会被解雇(收益率j在For循环内)。 但是,Yield i被执行了,我这里是1。倒计时(1) 将1返回到上一次递归。
b)中 countDown(4)中j的倒计时(5)
countDown(3)中j的倒计时(4)
countDown(2)中j的countDown(3)
countDown(1)= 1中的j的countDown(2)。 j的值现在为'1'。因此,在倒计时(1)中的For j是真的。 因此,它会导致Yield j = 1.结果countDown(2)返回1 这是j被分配给我的地方。
c)中 countDown(4)中j的倒计时(5)
countDown(3)中j的倒计时(4)
countDown(3)= 1中的j的countDown(3) j的值现在为'1'。因此,倒计时中的For j(2)是真的。 因此,它会导致收益率j = 1.因此,countDown(3)返回1
...
e)countDown(4)= 1中j的倒计时(5) count Down(4)返回的值为1。 因此,j是1.所以,countDown中的for j(4) 被执行。
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的倒计时(5),其中j = 1(产量j是执行的最后一个语句)countDown(3)中j的倒计时(4),其中j = 1
countDown(3),其中j为countDown(2),其中j = 1
countndown(1),其中j为countDown(1),其中j = 1
倒计时(1)执行Yield i,因为上一次迭代,步骤a)yield是最后一个语句
递归递归
A) countDown(4)中j的倒计时(5),其中j = 1(产量j是执行的最后一个语句)
countDown(3)中j的倒计时(4),其中j = 1
countDown(3),其中j为countDown(2),其中j = 1
countDown(1)中j的倒计时(2),其中j = 1 倒计时(1)返回值1,j已经值为1, 所以,它执行下一步,即产生i,其中i = 2。 countDown(2)返回yield i = 2
b)中 countDown(4)中j的倒计时(5),其中j = 1(产量j是执行的最后一个语句)
countDown(3)中j的倒计时(4),其中j = 1
countDown(2)中j的countDown(3)
因为countDown(2)返回2,j得到这个新值j = 2
产量j被执行
c)中
...
E) countDown(4)中j的倒计时(5)变为2