【问题标题】:Is it safe to call a function from within the same function从同一个函数中调用函数是否安全
【发布时间】:2020-12-17 06:28:31
【问题描述】:

我一直在阅读排序算法。我遇到了合并排序的代码:

def mergeSort(arr):
    if len(arr) > 1:
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]
        #function calls itself here<<<<<<<<<<<<<<<<<<<<<<<<<
        mergeSort(L)# Sorting the first half
        mergeSort(R)# Sorting the second half

        i = j = k = 0
    
        # Copy data to temp arrays L[] and R[] 
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i] 
                i+= 1
            else: 
                arr[k] = R[j] 
                j+= 1
                k+= 1
    
        # Checking if any element was left 
        while i < len(L): 
            arr[k] = L[i] 
            i+= 1
            k+= 1
    
        while j < len(R): 
            arr[k] = R[j] 
            j+= 1
            k+= 1

# Code to print the list 
def printList(arr):
    for i in range(len(arr)):
        print(arr[i], end =" ")
    print() 

# driver code to test the above code 
if __name__ == '__main__': 
    #arr = [12, 11, 13, 5, 6, 7]
    arr = [38, 27, 43, 3, 9, 82, 10]
    print ("Given array is", end ="\n") 
    printList(arr) 
    mergeSort(arr) 
    print("Sorted array is: ", end ="\n") 
    printList(arr) 

# This code is contributed by Mayank Khanna 

如上所述,函数mergeSort() 是从自身内部调用的,这是一种好的做法吗?我的印象是它可能会导致错误。

【问题讨论】:

  • 是的,递归是完全正常且可以接受的。变量保存在堆栈中。
  • 递归的一个简单的好例子是找到一个数的阶乘。有时需要使用递归,这是一种很好的做法。

标签: python python-3.x function recursion


【解决方案1】:

TL;DR 通常没问题,但对于某些输入可能非常危险。

给定的mergeSort 函数,调用它自己——这个现象称为recursion

什么是递归

  1. 解决问题的常用方法,其中解决方案取决于对同一问题的较小实例的解决方案;比如遍历二叉树。
  2. 每次递归调用函数参数都被推入call stack,并且每次调用都有自己的局部变量。
  3. 递归可能导致漏洞,例如DNS open recursion
  4. 如果因未定义停止条件或处理导致大量递归调用的输入而被滥用,则会发生stack overflow(这意味着call stack 已被使用到最大)。李>
  5. Any recursive solution can be converted to an iterative solution (solution using loops)

总结

  1. 当函数调用一段合理的时间时,递归是安全的。

  2. Python 的默认递归限制是1000,因此函数不能调用自身超过1000 次。

您可以使用getrecursionlimit 进行验证:

import sys
print(sys.getrecursionlimit())

然后用setrecursionlimit改一下:

new_recursion_limit = 1500
sys.setrecursionlimit(new_recursion_limit)
  1. 递归可能并且将会导致漏洞,最好在处理用户输入时避免使用 - 有利于迭代解决方案。

附言

现在您也知道我们的网站是以什么命名的了!

【讨论】:

  • set_recursion_limit 是在 Python 中增加递归限制的简单方法
【解决方案2】:

在自身内部调用函数没有问题,但您必须格外小心进入无限循环。执行此操作的一般良好做法是仅在函数末尾调用函数(这样可以减少混淆变量值的机会)并使用某种 if 语句或某种意义上的语句来提供出路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-14
    • 2013-05-15
    • 1970-01-01
    • 2011-10-31
    • 2021-12-15
    • 1970-01-01
    • 2013-05-10
    • 2010-10-10
    相关资源
    最近更新 更多