簡體   English   中英

用於中序遍歷的生成器函數

[英]Generator Function for inOrder traversal

我最近一直在研究我的生成器函數和表達式,但我不太確定我將如何解決這個問題。 如何使用生成器函數生成然后按順序打印值?

我使用 pythons 列表構建了我的 BST

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

如果我要打印中序遍歷,我沒有問題。 因此,如果我要為以下函數調用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])

我遇到的問題是讓我的 main 迭代函數中產生的內容。 我以為它應該是這樣的

test= inorder(bst)

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

它不是迭代整個函數 yields,而是在它開始之前簡單地停止迭代。

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

我需要做什么才能使我的函數發生器正確運行?

您的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表達式將生成器委托給另一個,從該子生成器產生直到它完成。 這樣你就可以正確地遞歸。

如果您使用的是較舊的 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就會自動停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM