在递归中调用带有和不带"return"的函数有什么区别?



我试图创建递归函数来生成Pascal三角形,如下所示。

numRows = 5
ans=[[1],[1,1]]

def pascal(arr,pre,idx):
if idx==numRows:
return ans

if len(arr)!=idx:
for i in range (0,len(pre)-1,1):
arr+=[pre[i]+pre[i+1]]

if len(arr)==idx:
arr+=[1]
ans.append(arr)
pascal([1],arr,idx+1)

a = pascal([1],ans[1],2)
return a

我得到的输出是一个空列表[ ]。但如果我在调用pascal作为时添加return

return pascal([1],arr,idx+1)

输出是正确的CCD_ 4。

据我所知,a应该由return ans分配。那么,为什么a在没有return的情况下调用pascal时没有得到答案,以及为什么在这种情况下return是必要的?

当使用递归时,通常会以某种方式组合返回。可能是一个和,就像斐波那契:

fibonacci(n+1) = fibonnaci(n)+fibonacci(n-1)

或者在矩阵后面加一行,就像你的例子一样。不管怎样,如果你没有退货,你就没有信息可以组合!考虑不返回的fibonnaci情况:

def fibonnaci(n):
if n<2:
return 1

fib_ans = fibonnaci(n-2)+fibonnaci(n-1)

在这种情况下,如果我调用fibonnaci(0)fibonnaci(1),输出将是1,就像如果idx==numRows返回ans一样,但如果我调用了fibonnaci(2),那么变量fib_ans将接收2,这是预期的答案,但它在函数范围之外可用。Python";将添加";return None到我函数的末尾,就在fib_ans属性的下面。所以,我需要返回fib_ans

据我所知,如果你想拿回一个值,你需要"返回";陈述

关键是如果你没有;返回";,你将得不到任何价值。。。

希望这能有所帮助。。

对于所有具有return关键字的算法语言,它完全退出最近的函数,其结果是返回参数表达式的结果。例如

def test(v):
if v == 0:
return someFun(10)
...

如果v为零,则函数的结果为someFun(10)返回的值。函数的其余部分由…表示。。。除非CCD_ 18为非零,否则从不执行。

如果我们在没有return:的情况下写同样的东西

def test(v):
if v == 0:
someFun(10)
...

现在,当v为零时,仍然调用someFun(10),但它返回的值被丢弃,为了使其具有任何真正的意义,someFun需要做一些副作用,如打印、存储值、更新对象。此外,函数的所有其余部分由…表示。。。一旦CCD_ 23完成。

对于Python和许多其他语言来说,根本没有return并不意味着它不返回任何内容。在Python中,每个函数/方法的最后一行都有一个不可见的return None

执行pascal([1],arr,idx+1)时,您正在执行递归调用,但随后会丢弃它返回的值。如果要将其返回给调用者,则需要显式使用return pascal(...)

事实上,无论如何,递归在本例中都不是必需的。您可以很容易地重构代码以使用一个简单的for循环。例如:

def pascal(numRows):
ans = [[1]]
for _ in range(1, numRows):
pre = ans[-1]
arr = [1]
for i in range(0,len(pre)-1,1):
arr+=[pre[i]+pre[i+1]]
arr+=[1]
ans.append(arr)
return ans
print(pascal(5))

(根据惯例,我在这里使用名称_作为for循环变量,因为它是一个不在循环中使用的伪变量,但如果您愿意,可以使用其他变量,例如row。(

上面的代码尽可能接近原始代码,但您也应该考虑使用arr.append(value)来代替arr += [value]——这将是向列表添加单个值的正常方式。

最新更新