递归生成器和 send()
有谁知道 send() 递归使用时如何与生成器一起使用?我预计该值将传递给当前生成器,然后当前生成器可以将其传递给递归生成器......但似乎情况并非如此?一些示例代码:
def Walk(obj):
recurse = (yield obj)
if not recurse:
print 'stop recurse:', recurse
return
if isinstance(obj, list):
print 'is list:', obj
for item in obj:
print 'item loop:', item
walker = Walk(item)
for x in walker:
print 'item walk:', x
recurse = (yield x)
print 'item walk recurse:', recurse
walker.send(recurse)
root = ['a', ['b.0', ['b.0.0']]]
walker = Walk(root)
for i, x in enumerate(walker):
print i, x
print 'send true'
walker.send(True)
所需的输出应该是每个级别递归的每个值:
0 ['a', ['b.0', ['b.0.0']]]
1 'a'
2 ['b.0', ['b.0.0']]
3 'b.0'
4 ['b.0.0']
5 'b.0.0'
最终发生的情况是:
0 ['a', ['b.0', ['b.0.0']]]
send true
is list: ['a', ['b.0', ['b.0.0']]]
item loop: a
item walk: a
item walk recurse: None
stop recurse: None
看起来带有 recurse = (yield)
的内循环不等待值待发送。或者什么。目前尚不清楚内循环递归值如何变得无;它的调用者确实调用了send()
。
最终,目标基本上是递归地遍历树结构,但让最顶层的调用者能够指定何时不递归到子结构。例如,
walker = Walk(root)
for node in walker:
if CriteriaMet(node):
walker.send(True)
else:
walker.send(False)
Does anyone know how send() works with generators when used recursively? I expected the value to be passed to the current generator, which could then pass it down to the recursed-generator...but it seems that is not the case? Some example code:
def Walk(obj):
recurse = (yield obj)
if not recurse:
print 'stop recurse:', recurse
return
if isinstance(obj, list):
print 'is list:', obj
for item in obj:
print 'item loop:', item
walker = Walk(item)
for x in walker:
print 'item walk:', x
recurse = (yield x)
print 'item walk recurse:', recurse
walker.send(recurse)
root = ['a', ['b.0', ['b.0.0']]]
walker = Walk(root)
for i, x in enumerate(walker):
print i, x
print 'send true'
walker.send(True)
The desired output is should be each value at each level recursion:
0 ['a', ['b.0', ['b.0.0']]]
1 'a'
2 ['b.0', ['b.0.0']]
3 'b.0'
4 ['b.0.0']
5 'b.0.0'
What ends up happening is:
0 ['a', ['b.0', ['b.0.0']]]
send true
is list: ['a', ['b.0', ['b.0.0']]]
item loop: a
item walk: a
item walk recurse: None
stop recurse: None
It looks like the inner-loop with recurse = (yield)
doesn't wait for a value to be sent. Or something. Its not really clear how the inner-loop recurse
value is getting None
; its caller does call send()
.
Ultimately, the goal is basically to walk over a tree-structure recursively, but have the top-most caller be able to specify when not to recurse into a substructure. e.g.,
walker = Walk(root)
for node in walker:
if CriteriaMet(node):
walker.send(True)
else:
walker.send(False)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
需要意识到的重要一点是 send() 也会消耗!
来自 http://docs.python.org/reference/expressions.html#generator。发送:
以下是对代码的快速修改,使其按预期输出:
输出:
The important thing to realize is that send() also consumes!
From http://docs.python.org/reference/expressions.html#generator.send:
Here is a quick re-working of your code to get it to output as expected:
Output: