简体   繁体   English

用于中序遍历的生成器函数

[英]Generator Function for inOrder traversal

I've been working on my generator functions and expressions recently, but I'm not quite sure how I would tackle this.我最近一直在研究我的生成器函数和表达式,但我不太确定我将如何解决这个问题。 How could I use a generator function to yield and then later print the values in order?如何使用生成器函数生成然后按顺序打印值?

I built my BST using pythons list我使用 pythons 列表构建了我的 BST

bst = [20, [10, [5, [2, [], []], [8, [], []]], [15, [], []]], [30, [25, [22, [], []], [27, [], []]], [35, [], [37, [], []]]]]

If I were to print the inorder traversal, I have no problem.如果我要打印中序遍历,我没有问题。 So if I were to call inorder(bst) for the following function:因此,如果我要为以下函数调用inorder(bst)

def inorder(tree):
    if tree:
        inorder(tree[1])
        print (tree[0])
        inorder(tree[2])

I get this output.我得到这个输出。

2
5
8
10
15
20
22
25
27
30
35
37

I would think that a generator expression would be equally as simple我认为生成器表达式同样简单

def inorder(tree):
    if tree:
        inorder(tree[1])
        yield (tree[0])
        inorder(tree[2])

The problem I'm running into is getting my main to iterate through what's yielded in the function.我遇到的问题是让我的 main 迭代函数中产生的内容。 I thought it was supposed to be something like我以为它应该是这样的

test= inorder(bst)

for i in range(0,len(l)): # l is the number of items in bst
    print (next(test))

Instead of iterating over the entire functions yields, it simply stops the iterable seemingly before it starts.它不是迭代整个函数 yields,而是在它开始之前简单地停止迭代。

    20
Traceback (most recent call last):
  File "functionGenerator.py", line 64, in <module>
    print(next(test))
StopIteration

What do I need to do to make my function generator operate correctly?我需要做什么才能使我的函数发生器正确运行?

Your inorder() implementation doesn't correctly recurse.您的inorder()实现没有正确递归。 You are only printing the current top node of your tree.您只是在打印树的当前顶部节点。 That's because only calling inorder(tree[1]) or inorder(tree[2]) returns a generator object, you are not iterating over those generators.那是因为仅调用inorder(tree[1])inorder(tree[2])返回一个生成器对象,您不会迭代这些生成器。

Use使用

def inorder(tree):
    if tree:
        yield from inorder(tree[1])
        yield tree[0]
        yield from inorder(tree[2])

The yield from expression delegates the generator to another, yielding from that sub-generator until it is done. yield from表达式将生成器委托给另一个,从该子生成器产生直到它完成。 That way you properly recurse.这样你就可以正确地递归。

If you are using an older Python release (before Python 3.3), you need to manually iterate over the recursive calls:如果您使用的是较旧的 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

Next, you can just iterate over the inorder() generator:接下来,您可以遍历inorder()生成器:

>>> for node in inorder(bst):
...     print(node)
...
2
5
8
10
15
20
22
25
27
30
35
37

although using next() works too:虽然使用next()也有效:

>>> tree = inorder(bst)
>>> print(next(tree))
2
>>> print(next(tree))
5

but iteration is cleaner and stops automatically once StopIteration is raised.但是迭代更干净并且一旦引发StopIteration就会自动停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM