[英]Python Namespaces in Recursive Functions
與我到達那里相比,我的問題相對簡單。 Python中的遞歸函數每次函數調用自身時都會創建一個新的命名空間嗎?
我正在閱讀mergesort並閱讀本教程: https ://interactivepython.org/runestone/static/pythonds/SortSearch/TheMergeSort.html#lst-merge
def mergeSort(alist):
print("Splitting ",alist)
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
alist[k]=lefthalf[i]
i=i+1
else:
alist[k]=righthalf[j]
j=j+1
k=k+1
while i < len(lefthalf):
alist[k]=lefthalf[i]
i=i+1
k=k+1
while j < len(righthalf):
alist[k]=righthalf[j]
j=j+1
k=k+1
print("Merging ",alist)
alist = [54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)
我已經足夠了解分而治之,但我現在無法理解的是我上面提到的問題。 我可以遵循代碼,但我不太了解使用lefthalf作為傳遞給mergeSort的遞歸函數調用的參數。
我得到的是當mergeSort首先在底部調用時,alist被切入[54,26,93,17]和[17,27,31,44,55,20]。 這些是lefthalf和righthalf。 然后在lefthalf上調用mergeSort。 這是我感到困惑的地方。 對mergeSort的遞歸調用是否會創建一個全新的命名空間,這就是為什么傳入的lefthalf不會與函數中定義的lefthalf沖突的原因?
我知道答案是非常簡單和基本的,所以你的耐心非常感謝。 提前致謝!
是的,函數調用(任何函數調用,而不僅僅是遞歸調用)都會創建一個新的命名空間。 但是,當作為參數給出時,對象通過引用傳遞(在您的示例中,對象是列表)。
因此,新命名空間獲得它自己的引用副本,但它仍然引用與調用函數中相同的對象,如果更改該對象的內容,您將注意到調用函數的更改。
不確定我是否足夠清楚。 這是一個很好的圖表 ,可能有助於理解這是如何工作的。
對mergeSort的遞歸調用是否會創建一個全新的命名空間,[...]?
是。
只要解釋器遇到對函數的調用,它就會創建一個框架對象 ,並將其推送到框架堆棧 。 每次創建一個幀時,該幀都被賦予其自己的私有名稱空間,其中幀中的每個變量都被重新定義。
在您的情況下,每次調用mergeSort()
,Python都會創建一個新的框架對象,並將其推送到框架堆棧。 每次Python從調用mergeSort()
創建一個幀時, lefthalf
重新定義lefthalf
。
通過幾次調用print()
,您可以在每次調用mergeSort()
看到lefthalf
的值:
This is the 1 recursive call to mergeSort()
lefthalf is: [54, 26, 93, 17]
alist is: [54, 26, 93, 17, 77, 31, 44, 55, 20]
This is the 2 recursive call to mergeSort()
lefthalf is: [54, 26]
alist is: [54, 26, 93, 17]
This is the 3 recursive call to mergeSort()
lefthalf is: [54]
alist is: [54, 26]
This is the 4 recursive call to mergeSort()
This is the 5 recursive call to mergeSort()
This is the 6 recursive call to mergeSort()
lefthalf is: [93]
alist is: [93, 17]
This is the 7 recursive call to mergeSort()
This is the 8 recursive call to mergeSort()
This is the 9 recursive call to mergeSort()
lefthalf is: [77, 31]
alist is: [77, 31, 44, 55, 20]
This is the 10 recursive call to mergeSort()
lefthalf is: [77]
alist is: [77, 31]
This is the 11 recursive call to mergeSort()
This is the 12 recursive call to mergeSort()
This is the 13 recursive call to mergeSort()
lefthalf is: [44]
alist is: [44, 55, 20]
This is the 14 recursive call to mergeSort()
This is the 15 recursive call to mergeSort()
lefthalf is: [55]
alist is: [55, 20]
This is the 16 recursive call to mergeSort()
This is the 17 recursive call to mergeSort()
[17, 20, 26, 31, 44, 54, 55, 77, 93]
>>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.