Python生成器

时间:2011-08-04 01:07:13

标签: python

3 个答案:

答案 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)

  1. countDown(5)获取下一个countDown(4)
  2. countDown(4)获取下一个countDown(3)
  3. countDown(3)获取下一个countDown(2)
  4. countDown(2)获取下一个countDown(1)
  5. countDown(1)获取下一个countDown(0)
  6. countDown(0) yield i = 0,countDown(0)停止
  7. countDown(1) yield j = 0
  8. countDown(2) yield j = 0
  9. countDown(3) yield j = 0
  10. countDown(4) yield j = 0
  11. countDown(5) yield j = 0
  12. countDown(5)获取下一个countDown(4)
  13. countDown(4)获取下一个countDown(3)
  14. countDown(3)获取下一个countDown(2)
  15. countDown(2)获取下一个countDown(1)
  16. countDown(1) yield i = 1,countDown(1)停止
  17. countDown(2) yield j = 1
  18. countDown(3) yield j = 1
  19. countDown(4) yield j = 1
  20. countDown(5) yield j = 1
  21. countDown(5)获取下一个countDown(4)
  22. countDown(4)获取下一个countDown(3)
  23. countDown(3)获取下一个countDown(2)
  24. countDown(2) yield i = 2,countDown(2)停止
  25. countDown(3) yield j = 2
  26. countDown(4) yield j = 2
  27. countDown(5) yield j = 2
  28. countDown(5)获取下一个countDown(4)
  29. countDown(4)获取下一个countDown(3)
  30. countDown(3) yield i = 3,countDown(3)停止
  31. countDown(4) yield j = 3
  32. countDown(5) yield j = 3
  33. countDown(5)获取下一个countDown(4)
  34. countDown(4) yield i = 4,countDown(4)停止
  35. countDown(5) yield j = 4
  36. countDown(5) yield i = 5,countDown(5)停止

  37. 不知道为什么我无法编辑您的帖子。

    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的cou​​ntDown(3)

countDown(1)中j的cou​​ntDown(2)

countDown(0)中j的cou​​ntDown(1)

countDown(0)如果语句失败并且不返回任何内容

递归返回阶段

a)

countDown(4)中j的倒计时(5)

countDown(3)中j的倒计时(4)

countDown(2)中j的cou​​ntDown(3)

countDown(1)中j的cou​​ntDown(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的cou​​ntDown(3)

countDown(1)= 1中的j的cou​​ntDown(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的cou​​ntDown(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的cou​​ntDown(3)
                 因为countDown(2)返回2,j得到这个新值j = 2                  产量j被执行 c)中

在countDown(4)中j的倒计时(5),其中j = 1(产量j是执行的最后一个语句)

在countDown(3)中j的倒计时(4),其中j = 1                   因为倒计时(3)返回值2,如b)所示,j的新值是2

...

E) countDown(4)中j的倒计时(5)变为2