yeild 的递归输出问题

Zoom.Quiet zoom.quiet@gmail.com
发件人当地时间 发送时间 17:57 (GMT+08:00)。发送地当前时间:下午8:05。 ✆
日期      2011年8月25日 下午5:57
主题      yeild 的递归输出问题

问题

背景::

e.g: 类似数据对象

   1 DATA= {
   2 'SEQ':{
   3    "id1":['id11', 'id12']
   4    ,"id11":['id111']
   5    ,"id111":['id1111']
   6    ,"id12":['id21']
   7    ,"id21":['id211', 'id212']
   8    }
   9 ,'DESC':{'id1':{'title':1,'type':'folder'}
  10    ,'id11':{'title':11,'type':'folder'}
  11    ,'id12':{'title':12,'type':'file'}
  12    ,'id111':{'title':111,'type':'file'}
  13    ,'id1111':{'title':1111,'type':'file'}
  14    ,'id21':{'title':21,'type':'folder'}
  15    ,'id211':{'title':211,'type':'file'}
  16    ,'id212':{'title':212,'type':'file'}
  17    }
  18 }

当前::

   1 import types
   2 
   3 def _exp_all_item(drdf, seq, exp):
   4    if types.ListType is type(seq):
   5        for seqid in seq:
   6            if seqid in drdf['SEQ']:
   7                print "<li>%s</ui>" % drdf['DESC'][seqid]['title']
   8                _exp_all_item(drdf,drdf['SEQ'][seqid],exp)
   9            else:
  10                _exp_all_item(drdf,seqid,exp)
  11    else:
  12        if seq in drdf['SEQ']:
  13            print "<li>%s</ui>" % drdf['DESC'][seq]['title']
  14            _exp_all_item(drdf,drdf['SEQ'][seq],exp)
  15        else:
  16            print "<li>%s</li>" % drdf['DESC'][seq]['title']
  17 if __name__ == "__main__":
  18    htm = ""
  19    _exp_all_item(DATA, 'id1', htm)

可以很好的输出所有层次的数据:

   <li>1</ui>
   <li>11</ui>
   <li>111</ui>
   <li>1111</li>
   <li>12</ui>
   <li>21</ui>
   <li>211</li>
   <li>212</li>

但是!如果数据非常大,立即就有:

RuntimeError: maximum recursion depth exceeded in cmp

目标: 使用 yield 可以进行方便的生成器,迭代化:

   1 def _exp_all_item(drdf, seq, exp):
   2    if types.ListType is type(seq):
   3        for seqid in seq:
   4            if seqid in drdf['SEQ']:
   5                print "<li>%s</ui>" % drdf['DESC'][seqid]['title']
   6                yield _exp_all_item(drdf,drdf['SEQ'][seqid],exp)
   7            else:
   8                yield _exp_all_item(drdf,seqid,exp)
   9    else:
  10        if seq in drdf['SEQ']:
  11            print "<li>%s</ui>" % drdf['DESC'][seq]['title']
  12            yield _exp_all_item(drdf,drdf['SEQ'][seq],exp)
  13        else:
  14            print "<li>%s</li>" % drdf['DESC'][seq]['title']

问题!

比如说:

   1 def _exp_all_item(drdf, seq, exp):
   2    if types.ListType is type(seq):
   3        for seqid in seq:
   4            if seqid in drdf['SEQ']:
   5                exp+=  "<li>%s</ui>" % drdf['DESC'][seqid]['title']
   6                _exp_all_item(drdf,drdf['SEQ'][seqid],exp)
   7            else:
   8                _exp_all_item(drdf,seqid,exp)
   9    else:
  10        if seq in drdf['SEQ']:
  11            exp+=  "<li>%s</ui>" % drdf['DESC'][seq]['title']
  12            _exp_all_item(drdf,drdf['SEQ'][seq],exp)
  13        else:
  14            exp+=  "<li>%s</li>" % drdf['DESC'][seq]['title']
  15        return exp

这样,并不能完成所有数据的统一收集,只能输出最后的一次迭代,,, 这事儿,怎么想呢?

Limodou

limodou limodou@gmail.com
发件人当地时间 发送时间 19:49 (GMT+08:00)。发送地当前时间:下午8:07。 ✆

我理解你是想将所有数据放到一个变量中,代码如下:

   1 def _exp_all_item(drdf, seq, exp):
   2    if types.ListType is type(seq):
   3        for seqid in seq:
   4            if seqid in drdf['SEQ']:
   5                yield "<li>%s</ui>" % drdf['DESC'][seqid]['title']
   6                for x in _exp_all_item(drdf,drdf['SEQ'][seqid],exp):
   7                    yield x
   8            else:
   9                for x in _exp_all_item(drdf,seqid,exp):
  10                    yield x
  11    else:
  12        if seq in drdf['SEQ']:
  13            yield "<li>%s</ui>" % drdf['DESC'][seq]['title']
  14            for x in _exp_all_item(drdf,drdf['SEQ'][seq],exp):
  15                yield x
  16        else:
  17            yield "<li>%s</li>" % drdf['DESC'][seq]['title']
  18 
  19 if __name__ == '__main__':
  20    s = list(_exp_all_item(DATA, 'id1', ''))
  21    print s

上面的关键就是,在递归时,对于返回的结果要通过for将generator解开,再通过yield返回。而不是直接返回一个generator.

$ python demoyield.py
['<li>1</ui>'
, '<li>11</ui>'
, '<li>111</ui>'
, '<li>1111</li>'
, '<li>12</ui>'
, '<li>21</ui>'
, '<li>211</li>'
, '<li>212</li>'
]

感触

受教了!


反馈

创建 by -- ZoomQuiet [2011-08-25 12:10:49]

MiscItems/2011-08-25 (last edited 2011-08-25 12:10:48 by ZoomQuiet)