在python中遇到基本递归问题

时间:2012-05-15 18:38:57

标签: python recursion

我正在研究如何像计算机科学家一样思考,目前我正在努力掌握递归。我遇到了其中一个问题,所以我希望你能帮助我。

我正在编写一个函数,它找到列表的递归最小值,其元素是整数,整数列表,整数列表列表等。

这是我目前的版本:

def recursive_min(nested_num_list):
    """
      >>> recursive_min([9, [1, 13], 2, 8, 6])
      1
      >>> recursive_min([2, [[100, 1], 90], [10, 13], 8, 6])
      1
      >>> recursive_min([2, [[13, -7], 90], [1, 100], 8, 6])
      -7
      >>> recursive_min([[[-13, 7], 90], 2, [1, 100], 8, 6])
      -13
    """
    min = nested_num_list[0]
    while type(min) == type([]):
        min = min[0]
    for item in nested_num_list:
        if type(item) == type([]):
            recursive_min(item)
        elif item < min:
            min = item
    return min

但是,这只能找到最高级别的最小值,所以我现在的代码没有进入列表的深度。

现在,看看答案,我知道我的版本应该是这样的:

def recursive_min(nested_num_list):
    """
      >>> recursive_min([9, [1, 13], 2, 8, 6])
      1
      >>> recursive_min([2, [[100, 1], 90], [10, 13], 8, 6])
      1
      >>> recursive_min([2, [[13, -7], 90], [1, 100], 8, 6])
      -7
      >>> recursive_min([[[-13, 7], 90], 2, [1, 100], 8, 6])
      -13
    """
    min = nested_num_list[0]
    while type(min) == type([]):
        min = min[0]
    for item in nested_num_list:
        if type(item) == type([]):
            min_of_elm = recursive_min(item)
            if min_of_elm < min:
                min = min_of_elm
        elif item < min:
            min = item
    return min

请注意,它不是仅执行recursive_min(item),而是将其分配给变量,并将其与当前min进行比较。我不明白为什么我需要这样做,在我看来,如果我在嵌入式列表上执行整个函数,并且这是一个整数列表,那么它应该转到elif语句(而不是if语句)并正确地比较这些值。

我知道我必须在这里遗漏一些有关递归的内容。我真的很感激您可以给我的任何见解,以帮助我理解是什么让第二个版本工作,但第一个版本失败。

谢谢!

2 个答案:

答案 0 :(得分:2)

为什么会有效?你调用该函数,它会递归,直到找到min。那它做了什么?它依次退出所有递归,直到它回到顶层。那时,min的价值是多少?在你开始递归之前到底是什么,因为你从未从递归函数中捕获返回值。

不要忘记函数的每次调用都有自己的局部变量,因此它自己的本地值为min

答案 1 :(得分:0)

有很多方法可以解决这个问题。就个人而言,我更喜欢更实用的方法 - 只使用列表上的递归,没有循环或局部变量。它肯定是不是解决问题的最有效方法,但它简单而优雅:

def recursive_min(num_list):
    return aux_min(num_list[1:], num_list[0]) if num_list else None

def aux_min(num_list, min_num):
    if not num_list:
        return min_num
    elif not isinstance(num_list, list):
        return min(num_list, min_num)
    else:
        return min(aux_min(num_list[0],  min_num),
                   aux_min(num_list[1:], min_num))

在上面的代码中,main函数是recursive_min,它调用辅助函数aux_min。反过来,aux_min会收到一个列表和当前最小值,并在三种情况下分解问题:

  1. 如果列表为空,则返回当前最小值
  2. 如果它是一个数字而不是一个列表,则返回数字与当前最小值之间的最小值
  3. 如果是列表,则递归返回其第一个元素与列表其余部分之间的最小值
  4. 它适用于列表列表,因为在第三种情况下,第一个元素可能是列表本身。