如果我们把递归从图中去掉,可能更容易理解。下面是一个类似的构造:def funcA(lis, json, target):
return json[target]
def funcB(lis, json, target):
return funcA(lis[1:], json[lis[0]], target)
>>> final_json = funcB(my_list, my_json, 'ID')
>>> print(final_json)
在这里,我们可以遵循执行路径:我们调用funcB并传递一些参数。在
funcB,依次调用funcA,并传递一些参数。在
funcA返回一个返回funcB的值。在
该值依次由funcB返回。在
funcB返回的值被分配给final_json。在
现在,您的问题是,如果我们将funcB重新定义为:
^{2}$
通过这种重新定义,以及其他一切都相同,执行路径更像:我们调用funcB并传递一些参数。在
funcB,依次调用funcA,并传递一些参数。在
funcA返回一个返回funcB的值。在
该值被funcB忽略。在
funcB结束时不返回值,因此默认情况下它返回None。在
funcB返回的值被分配给final_json。在
因为funcB从不显式返回它从funcA获得的值,所以默认情况下返回None。在
由于递归函数只是一个调用自身的函数,它的行为与调用不同函数的函数没有什么不同。在
以下是您的功能:def recur(lis, json, target):
if lis[0] == target:
return json[target]
else:
return recur(lis[1:], json[lis[0]], target)
>>> final_json = funcB(my_list, my_json, 'ID')
>>> print(final_json)
让我们按照上述相同的过程进行,假设它将重复一次:我们调用recur并传递一些参数。在
recur反过来,再次调用recur并传递一些参数。在
对recur的第二次调用返回第一次调用的值。在
对recur的第一次调用接受该值并将其返回给我们。在
对recur的第一次调用返回的值被分配给final_json。在
但是,如果我们删除return,那么:def recur(lis, json, target):
if lis[0] == target:
return json[target]
else:
recur(lis[1:], json[lis[0]], target)我们调用recur并传递一些参数。在
recur反过来,再次调用recur并传递一些参数。在
对recur的第二次调用返回第一次调用的值。在
对recur的第一次调用接受该值并忽略它。在
对recur的第一次调用结束时没有返回值,因此默认情况下它返回None。在
对recur的第一次调用返回的值被分配给final_json。在
同样,由于对recur的第一次调用从未显式返回第二次调用recur得到的结果,因此默认情况下返回None。在UPDATE: Let me clarify what exactly is so confusing about this. If I add a print statement like such:def recur(lis, json, target):
if lis[0] == target:
print(json[tagert])
return json[target]
else:
recur(lis[1:], json[lis[0]], target)
my print statement will display the expected value of the JSON. I don't know how else to phrase this. Given that the line preceding the return statement gives the result I expect (without the return statement in the else) why is the return statement in the else necessary?
print是全局的,它写入stdout而不考虑函数深度或堆栈帧。另一方面,return存在于函数级别,并且只影响单个函数调用返回的值。如果该函数调用对它调用的函数的返回值不做任何操作,则该值将丢失。在Is this specific to Python? I'm a bit rusty but I seem to remember languages like Haskell handling this more elegantly where, I believe, I don't need to return the value of the recursive call.
Haskell函数只定义一个值;不需要显式的return,因为函数的整个主体都是隐式的。其他语言,如Lisp族,总是返回块中最后一行的值,因此在本例中显式的return也是不必要的。在
请注意,在这两种情况下,return语句的两个都将丢失,而不仅仅是第二个;这通常与^{有关,与递归调用无关。在
Python和大多数其他主流语言都需要显式的return,如果您想返回任何有用的值。在