我最近一直在研究我的生成器函数和表达式,但我不太确定如何解决这个问题。我怎样才能使用生成器函数来生成然后按顺序打印值?
我使用pythons list
构建了我的BSTbst = [20, [10, [5, [2, [], []], [8, [], []]], [15, [], []]], [30, [25, [22, [], []], [27, [], []]], [35, [], [37, [], []]]]]
如果我要打印inorder遍历,我没有问题。因此,如果我要为inorder(bst)
调用以下函数:
def inorder(tree):
if tree:
inorder(tree[1])
print (tree[0])
inorder(tree[2])
我得到了这个输出。
2
5
8
10
15
20
22
25
27
30
35
37
我认为生成器表达式同样简单
def inorder(tree):
if tree:
inorder(tree[1])
yield (tree[0])
inorder(tree[2])
我遇到的问题是让我的主要人员迭代在函数中产生的东西。我以为它应该像
test= inorder(bst)
for i in range(0,len(l)): # l is the number of items in bst
print (next(test))
它不是迭代整个函数的产生,而是在它开始之前看似只是停止迭代。
20
Traceback (most recent call last):
File "functionGenerator.py", line 64, in <module>
print(next(test))
StopIteration
我需要做些什么才能使我的函数发生器正常运行?
答案 0 :(得分:3)
您的inorder()
实施未正确递归。您只打印树的当前顶级节点。那是因为只调用inorder(tree[1])
或inorder(tree[2])
返回一个生成器对象,你不会迭代这些生成器。
使用
def inorder(tree):
if tree:
yield from inorder(tree[1])
yield tree[0]
yield from inorder(tree[2])
yield from
expression将生成器委托给另一个生成器,从该子生成器生成,直到完成为止。这样你就可以正确递归。
如果您使用较旧的Python版本(在Python 3.3之前),则需要手动迭代递归调用:
def inorder(tree):
if tree:
for sub in inorder(tree[1]):
yield sub
yield tree[0]
for sub in inorder(tree[2]):
yield sub
接下来,您可以遍历inorder()
生成器:
>>> for node in inorder(bst):
... print(node)
...
2
5
8
10
15
20
22
25
27
30
35
37
虽然使用next()
也有效:
>>> tree = inorder(bst)
>>> print(next(tree))
2
>>> print(next(tree))
5
但迭代更清晰,并在StopIteration
被引发后自动停止。