簡體   English   中英

為什么“yield”關鍵字沒有在我的應用程序中生成預期的生成器? (歸並排序算法)

[英]Why is "yield" keyword not producing the expected generator in my application? (Merge sort algorithm)

為什么我的yield關鍵字沒有產生預期的輸出?

我正在使用遞歸算法(合並排序)並使用yield以便我可以在每次更改(排序)時遍歷列表。

def MergeSort(lst):

    if len(lst) > 1:
        middle = len(lst)//2
        lefthalf = lst[:middle]
        righthalf = lst[middle:]

        MergeSort(lefthalf)
        MergeSort(righthalf)

        i,j,k= 0,0,0

        while i<len(lefthalf) and j<len(righthalf):
            if lefthalf[i] < righthalf[j]:
                lst[k] = lefthalf[i]
                i+=1
            else:
                lst[k] = righthalf[j]
                j+=1

            k+=1

        while i<len(lefthalf):
            lst[k]=lefthalf[i]
            i+=1
            k+=1

        while j<len(righthalf):
            lst[k]=righthalf[j]
            j+=1
            k+=1

        yield lst
a = MergeSort([2,3,566,78,8])
for i in a:
    print(i)
[2, 3, 566, 78, 8]

相反,我希望實現如下目標:(隨着算法的工作)

[2, 3, 566, 78, 8]
[2, 3, 566, 8, 78]
[2, 3, 8, 78, 566]

如果我使用return語句,它將按預期工作並對列表進行排序,但是當我使用yield我無法獲得合適的生成器。 我還嘗試將yield放在while語句和其他幾乎所有地方。 我怎樣才能解決這個問題? 我錯過了什么?

因為你讓MergeSort成為一個生成器,而生成器是惰性的,你的遞歸調用實際上不做任何排序; 它們只返回生成器,在您遍歷它們之前不會做任何工作。 你的整個函數也只產生一個列表,因為它只包含一個yield語句,而且它不在循環中,所以它只執行一次。

解決這兩個問題的方法是使用yield from MergeSort(...)來耗盡您遞歸創建的生成器。 這將耗盡它們以便它們進行排序工作,並且還會導致外部生成器生成任何內部生成器生成的生成器。 因此,更改這兩行:

        yield from MergeSort(lefthalf)
        yield from MergeSort(righthalf)

例子:

>>> for i in MergeSort([2, 3, 566, 78, 8]):
...     print(i)
... 
[2, 3]
[8, 78]
[8, 78, 566]
[2, 3, 8, 78, 566]

請注意,您沒有看到相同長度的列表; 遞歸調用在較短的列表中,因此它們產生較短的列表。 在基本情況下,您也沒有看到長度為 1 的列表,因為您的yield lst語句位於if len(lst) > 1:塊內。 如果取消該行的縮進以使yield lst成為無條件,則可以看到每次調用的結果:

>>> for i in MergeSort([2, 3, 566, 78, 8]):
...     print(i)
... 
[2]
[3]
[2, 3]
[566]
[78]
[8]
[8, 78]
[8, 78, 566]
[2, 3, 8, 78, 566]

暫無
暫無

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

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