【问题标题】:Can't understand how recursive functions can work without return statement in Python无法理解递归函数如何在没有 Python 中的 return 语句的情况下工作
【发布时间】:2018-05-07 07:07:39
【问题描述】:

您好,我正在努力理解递归在 Python 中的工作原理。我特别在 Python 3.5 版本中工作。我正在研究 Python 中合并排序算法的这种实现:

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)

我无法理解这个实现是如何工作的,因为 MergeSort 函数没有返回语句。此外,在函数体顶部对 MergeSort 的递归调用的结果不会分配给 lefthalf 和 righthalf 变量。所以我无法理解如何将合并部分设置为与此实现一起使用。当我在我的 Python 中运行此代码时,它当然可以正常工作。我想我不能正确理解 Python 中的闭包,但如果有人能指出我正确的方向,那就太好了。提前致谢!

这是我理解的版本:

def mergeSort(alist):
    print("Splitting ",alist)
    if len(alist)>1:
        mid = len(alist)//2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]

        lefthalf = mergeSort(lefthalf)
        righthalf = 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)
    return(alist)

【问题讨论】:

  • 请将代码粘贴到问题中,不要使用外部链接,因为它们将来可能会中断,然后查看此问题的人将无法看到代码
  • 不看代码,最可能的解释是你正在查看的实现是就地排序列表,所以它改变了传递的列表in,因此不需要返回任何东西。
  • 非常抱歉各位!我编辑了我的帖子并粘贴了代码。

标签: python recursion mergesort


【解决方案1】:

python通过引用传递列表,这意味着原始列表可以被一个以列表作为参数的函数修改,所以当你调用函数时:

mergeSort(lefthalf)
mergeSort(righthalf)

lefthalfrighthalf 本身是已排序的,请注意外部对 mergeSort() 的调用也假定原始列表已被修改,它不会返回新的排序列表,正如我所说的 现有列表

【讨论】:

  • 好的,现在我可以看到了。像这里: def myfunc(alist): alist.append(2) def testf(alist): myfunc(alist) return(alist) testf([1,2,3]) 将返回 [1,2,3,2]
【解决方案2】:

我可以建议您在此处粘贴您的代码吗:http://pythontutor.com/visualize.html#mode=edit

然后单击“可视化执行”。您将看到您的代码如何执行以及每个变量的状态在每一行之后。

【讨论】:

    【解决方案3】:

    合并排序分两步进行。首先,它递归地将列表分成两半,直到它产生具有一个成员的列表。在您提到的代码中,if len(alist)&gt;1: 递归地打破了列表。 在第二步中,它只是以正确的顺序合并小块,直到创建第一个列表(但按顺序)。所以在第二步中,它首先将列表与一个成员结合起来,将列表与两个成员结合起来,依此类推。 while i &lt; len(lefthalf) and j &lt; len(righthalf):, 代码中的while i &lt; len(lefthalf):while j &lt; len(righthalf): 部分合并了这些部分。

    【讨论】:

    • 当然你的解释是对的,但我并没有为算法本身的理解而挣扎,而是在 Python 实现上,很抱歉我不会接受你的回答,因为它不是我的问题。
    猜你喜欢
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多