gpt4 book ai didi

python - 递归生成器和 send()

转载 作者:行者123 更新时间:2023-11-28 22:04:40 24 4
gpt4 key购买 nike

有谁知道 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) 的内部循环不等待发送值。或者其他的东西。目前还不清楚内循环 recurse 值是如何得到 None 的;它的调用者确实调用了 send()

最终,目标基本上是递归遍历树结构,但让最顶层的调用者能够指定何时递归到子结构中。例如,

walker = Walk(root)
for node in walker:
if CriteriaMet(node):
walker.send(True)
else:
walker.send(False)

最佳答案

重要的是要意识到 send() 也会消耗!
来自 http://docs.python.org/reference/expressions.html#generator.send :

Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

这里是对代码的快速重新处理,以使其按预期输出:

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)

recurse = None #first send must be None
while True:
try:
x = walker.send(recurse)
except StopIteration:
break
#print 'item walk:', x
recurse = (yield x)
#print 'item walk recurse:', recurse

root = ['a', ['b.0', ['b.0.0']]]

walker = Walk(root)
i = 0
x = walker.next()
while True:
print i, x
try:
x = walker.send(True)
except StopIteration:
break
i += 1

输出:

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

关于python - 递归生成器和 send(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6785052/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com