[英]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.