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