我正在学习递归生成器,并在网上找到了该程序。
我理解了顺序遍历的递归版本,但是在理解递归生成器时遇到了困难。
特别是我听不懂
我试图调试生成器并添加了手表,但是我发现递归调用执行了多次'yield x',并且未将其收集到最终结果中。
class Tree:
def __init__(self, label, left=None, right=None):
self.label = label
self.left = left
self.right = right
def __repr__(self, level=0, indent=" "):
s = level*indent + repr(self.label)
if self.left:
s = s + "\\n" + self.left.__repr__(level+1, indent)
if self.right:
s = s + "\\n" + self.right.__repr__(level+1, indent)
return s
def __iter__(self):
return inorder(self)
def tree(list):
n = len(list)
if n == 0:
return []
i = n // 2
return Tree(list[i], tree(list[:i]), tree(list[i + 1:]))
# Recursive Normal
def inorder(t):
if t:
inorder(t.left)
print(t.label)
inorder(t.right)
# Recursive Generator
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
t = tree("ABCDEFG")
# Tree will be like following
# D
# / \
# B F
# / \ / \
# A C E G
# / \ / \ / \ / \
# 0 0 0 0 0 0 0 0
# generating in order traversal
print([i for i in inorder(t)])
收益率x在for循环中的作用。
答案 0 :(得分:0)
不确定您要查找的是什么,但是也许是符合以下几点的事情:
class Tree:
def __init__(self, label, left=None, right=None):
self.label = label
self.left = left
self.right = right
def __repr__(self, level=0, indent=" "):
s = level*indent + repr(self.label)
if self.left:
s = s + "\n" + self.left.__repr__(level+1, indent)
if self.right:
s = s + "\n" + self.right.__repr__(level+1, indent)
return s
def __iter__(self):
return inorder(self)
def tree(list):
n = len(list)
if n == 0:
return []
i = n // 2
return Tree(list[i], tree(list[:i]), tree(list[i + 1:]))
def inorder(t):
if t:
for x in t.left:
yield x
yield t.label
for x in t.right:
yield x
t = tree("ABCDEFG")
[print(i.label) for i in t]
输出:
A
B
C
D
E
F
G
使用该代码,您可以改为:
[print('----------\n', i) for i in t]
将从A到G输出树中的每个分层节点。
编辑:如果您询问Generator的工作方式,也许这个例子可能会启发您:
>>> def list2gen(lst):
... for elem in lst:
... yield str(elem) + '_'
...
>>> print(list2gen([1,2,'7',-4]))
<generator object list2gen at 0x000001B0DEF8B0C0>
>>> print(list(list2gen([1,2,'7',-4])))
['1_', '2_', '7_', '-4_']
如果调试器多次中断,但是这些元素从未在生成的生成器中实现,则必须将其归因于调试器中的错误。我使用Python已有十多年了;他们曾经臭虫泛滥。在Python中,范例是“测试为王”和“避免手动调试”,但是我不同意这一点。 (我没有的唯一原因是缺少 Great IDE和调试器。)
答案 1 :(得分:0)
也许您不了解发电机是如何工作的?生成器不同于迭代器,它不是直接计算有价值的集合,而是动态获取所有值。如果inorder(t.left)
的结果未被for
循环遍历,则yield inorder(t.left)
将返回为t.left
创建的整个生成器。因为您的整个inorder
函数都是生成器。
很遗憾,我无法找到特定的描述文档。这是基于我的经验的描述。欢迎其他人更正我的意见。如果有人可以提供具体的官方说明,欢迎添加