python中的yield +递归使我恼火

时间:2013-02-24 01:16:07

标签: python recursion yield

对于我来说,理解何时收益和递归同时发生是如此复杂。 我想用我的代码遍历文件目录:

import os
def doc_iter(fpath):
  if os.path.isdir(fpath):
    for child in os.listdir(fpath):
      child=os.path.join(fpath,child)
      print  "this is ",child
      for cn in doc_iter(child):
        print "i am here1"
        yield cn
        print "yiedl1",cn
  else:
    print "i am here2"
    yield fpath
    print "yield2",fpath

有一个方向test,其中有三个子目录test1,test2,test3 在目录test1中,有两个文件test11,test12
在目录test2中,有两个文件test21,test22
在目录test3中,有两个文件test31,test32

    >>> a.next()
this is  /home/debian/test/test2
this is  /home/debian/test/test2/test22
i am here2
i am here1
i am here1
'/home/debian/test/test2/test22'
>>> a.next()
yiedl1 /home/debian/test/test2/test22
yiedl1 /home/debian/test/test2/test22
yield2 /home/debian/test/test2/test22
this is  /home/debian/test/test2/test21
i am here2
i am here1
i am here1
'/home/debian/test/test2/test21'
>>> a.next()
yiedl1 /home/debian/test/test2/test21
yiedl1 /home/debian/test/test2/test21
yield2 /home/debian/test/test2/test21
this is  /home/debian/test/test3
this is  /home/debian/test/test3/test32
i am here2
i am here1
i am here1
'/home/debian/test/test3/test32'
>>> a.next()
yiedl1 /home/debian/test/test3/test32
yiedl1 /home/debian/test/test3/test32
yield2 /home/debian/test/test3/test32
this is  /home/debian/test/test3/test31
i am here2
i am here1
i am here1
'/home/debian/test/test3/test31'
>>> a.next()
yiedl1 /home/debian/test/test3/test31
yiedl1 /home/debian/test/test3/test31
yield2 /home/debian/test/test3/test31
this is  /home/debian/test/test1
this is  /home/debian/test/test1/test11
i am here2
i am here1
i am here1
'/home/debian/test/test1/test11'
>>> a.next()
yiedl1 /home/debian/test/test1/test11
yiedl1 /home/debian/test/test1/test11
yield2 /home/debian/test/test1/test11
this is  /home/debian/test/test1/test12
i am here2
i am here1
i am here1
'/home/debian/test/test1/test12'
>>> a.next()
yiedl1 /home/debian/test/test1/test12
yiedl1 /home/debian/test/test1/test12
yield2 /home/debian/test/test1/test12
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

输出让我烦恼,
1.产量1的印数等于产量2?
2.至少有两个yield语句要运行,在教科书中,据说是when run into yield ,the program will be halt, the next next() make it continue ?? 3.let分析第一个next()的输出,为什么在i am here1产生cn后有两个i am here2" 4.what is the function of? 5.如何详细绘制计算树? 6.如果你编写了一个遍历目录的函数,

bottom=[]
import os 
def doc_iter(fpath):
    if os.path.isdir(fpath):
        for child in os.listdir(fpath):
            child=os.path.join(fpath,child)
            doc_iter(child)
    else:
        bottom.append(fpath)
    return bottom

输出是:

doc_iter("/home/debian/test")  

['/ home / debian / test / test2 / test22','/ home / debian / test / test2 / test21','/ home / debian / test / test','/ home / debian / test / test3 / test32','/ home / debian / test / test3 / test31','/ home / debian / test / test~','/ home / debian / test / test1 / test11','/ home / debian / test / TEST1 / TEST12' ]

函数和迭代器之间有不同, 在功能中:

doc_iter(child)
迭代器中的

for cn in doc_iter(child):
    yield 

这个例子有多复杂!

1 个答案:

答案 0 :(得分:1)

所以你的例子有点做作,并且在理解yield的工作原理时,你会遇到大部分困难。

walk_dir的每次迭代都会导致新的根路径传递给整个函数,这将导致函数的新迭代具有自己的yields

现在您看到打印相同路径的原因是因为每次调用next都会更深入地进入目录结构。

因此每个next()返回下一个目录或文件。你看到的停止迭代异常就是成语

for x in something_that_yeilds()知道如何停止。

我会在iterators, iterable, and generators上看到这篇非常精彩的文章。