我正在研究如何像计算机科学家一样思考,目前我正在努力掌握递归。我遇到了其中一个问题,所以我希望你能帮助我。
我正在编写一个函数,它找到列表的递归最小值,其元素是整数,整数列表,整数列表列表等。
这是我目前的版本:
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语句)并正确地比较这些值。
我知道我必须在这里遗漏一些有关递归的内容。我真的很感激您可以给我的任何见解,以帮助我理解是什么让第二个版本工作,但第一个版本失败。
谢谢!
答案 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
会收到一个列表和当前最小值,并在三种情况下分解问题:
它适用于列表列表,因为在第三种情况下,第一个元素可能是列表本身。