我试图弄清楚如何将此代码的运行绘制到递归树上,因为即使在调试时,我也不确定它的运行方式。
每个产量在做什么,为什么我都需要它们?
香港专业教育学院试图创建一个树,将每个运行与它的下一个递归连接,但我不知道在yield.data之后的内容,其中头是“ c”
class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next
def get_reverse_iterator(head):
if head.next:
for datum in get_reverse_iterator(head.next):
yield datum
yield head.data
lst = Node('a', Node('b', Node('c')))
for x in get_reverse_iterator(lst):
print(x)
结果应该是:
C
b
一种
最佳答案
要了解其工作原理,您需要了解递归的基本概念。假设我们不处理生成器;我们只希望在给定头节点的情况下反向打印列表的所有节点。我们通过将节点作为参数来调用函数print_reverse。如果节点的下一个字段为空,则只打印该字段的数据值。但是,如果next不为空,则它指向必须在打印当前节点之前打印的节点。因此,我们再次递归调用print_reverse以首先打印该节点。当print_reverse返回时,我们现在可以打印当前节点。当然,当我们递归调用print_reverse来打印下一个节点时,它可能会发现还有另一个必须首先打印到的节点,我们将再次递归调用print_reverse。因此,我们有:
class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next
def print_reverse(head):
if head.next:
print_reverse(head.next)
print(head.data)
lst = Node('a', Node('b', Node('c')))
print_reverse(lst)
在理解发电机问题之前,必须先理解以上代码。我们希望创建一个产生该值的生成器函数,而不是创建一个打印节点数据字段的函数print_reverse。因此,重命名函数并用
yield
语句替换print函数,并用yield from
语句递归调用是有意义的:class Node:
def __init__(self, data, next=None):
self.data = data
self.next = next
def get_reverse_iterator(head):
if head.next:
#print_reverse(head.next)
yield from get_reverse_iterator(head.next)
#print(head.data)
yield head.data
lst = Node('a', Node('b', Node('c')))
现在我们可以使用生成器,如下所示:
for x in get_reverse_iterator(lst):
print(x)
要么:
l = [x in get_reverse_iterator(lst)]
但是使用递归避免创建多个生成器对象的替代方法是:
def get_reverse_iterator(head):
stack = []
while head.next:
stack.append(head)
head = head.next
yield head.data
while len(stack):
head = stack.pop()
yield head.data