Python递归函数-这里发生了什么?
我用python编写了一个简单的阶乘函数,并嵌入了一系列调试代码,以帮助我理解正在发生的事情。然而,输出让我更加困惑。有人能帮我理解吗?(顺便说一句,如果出现打印输出定时问题,我运行了几次,但得到的输出完全相同。) 递归函数.pyPython递归函数-这里发生了什么?,python,function,recursion,factorial,Python,Function,Recursion,Factorial,我用python编写了一个简单的阶乘函数,并嵌入了一系列调试代码,以帮助我理解正在发生的事情。然而,输出让我更加困惑。有人能帮我理解吗?(顺便说一句,如果出现打印输出定时问题,我运行了几次,但得到的输出完全相同。) 递归函数.py def recursive(n): if n == 1: return 1 print ('n : {}'.format(n)) print ('recursive return value is: {}'.format(n*recursive(n
def recursive(n):
if n == 1:
return 1
print ('n : {}'.format(n))
print ('recursive return value is: {}'.format(n*recursive(n-1)))
return n*recursive(n-1)
x = recursive(5)
print('***** End result is: {}'.format(x))
(带行号)
(不带行号的清洁剂输出)
您的代码并不适合递归begginer,因此我在这里附加了另一个代码,它输出与您相同的值,但更容易理解
def重现(n):
如果n==1:
返回n
其他:
返回n*重复出现(n-1)
num=int(输入(“输入一个数字:”)
如果num<0:
打印(“对不起,负数不存在阶乘”)
elif num==0:
打印(“0的阶乘是1”)
其他:
print(“num”的阶乘,is,recur(num))
recur
函数将自然数n作为输入。如果n=1,这意味着1!=1,这应该是输出,没什么大不了的。
否则,函数将返回您的编号n*recur(n-1)。
例如:
——取n=4
n=1->false
现在返回(4)*重复(3)
(3) *复发(2)
(2) *复发(1)
现在n=1并返回(1)
括号()中的所有数字都将添加到整个乘积中,因此4*3*2*1=24。它之所以被称为递归,不是因为它调用自身,而是因为它向后启动:))
希望我能让你轻松一点
额外提示:
如果n==1:
返回n
在这里,您可以将
返回n
替换为返回1
,将具有相同的输出 该函数获取一个数字并计算结果
因此,对于5
的值,结果是5*4*3*2
,即120
使该函数成为递归函数是有意义的,因为5的阶乘是4的阶乘的5倍,4的阶乘是3的阶乘的4倍,依此类推。如果调用函数时使用n=1
,阶乘只返回为1
,递归可以停止
将此视为此处运行的实际算法:
可能有帮助的版本:
def recursive(n):
if n == 1:
return 1
print ('n : {}'.format(n))
res = recursive(n-1)
print ('return value is: {} (n={} * recursive({})={})'.format(n*res, n, n-1, res))
return res * n
x = recursive(5)
print('***** End result is: {}'.format(x))
变化:
- 不要做两次递归调用
- 在打印中添加了更多调试输出
n : 5
n : 4
n : 3
n : 2
return value is: 2 (n=2 * recursive(1)=1)
return value is: 6 (n=3 * recursive(2)=2)
return value is: 24 (n=4 * recursive(3)=6)
return value is: 120 (n=5 * recursive(4)=24)
***** End result is: 120
这是一个非常简单的例子,但是,复杂的递归方法可能会使任何人感到困惑。我发现,在每次通话(及其打印的信息)上打标签有助于我了解发生了什么。为此,只需在每次调用中向下传递递归级别(l
):
def recursive(n, l=0):
# l is the recurcion level
if n == 1:
return 1
print ('{} n : {}'.format(l * " ", n))
res = recursive(n-1, l + 1)
print ('{} return value is: {} (n={} * recursive({})={})'.format(
l * " ", n * res, n, n-1, res)
)
return res*n
现在可以稍微格式化一些内容:
n : 5
n : 4
n : 3
n : 2
return value is: 2 (n=2 * recursive(1)=1)
return value is: 6 (n=3 * recursive(2)=2)
return value is: 24 (n=4 * recursive(3)=6)
return value is: 120 (n=5 * recursive(4)=24)
***** End result is: 120
下面是一个查找整数阶乘的递归函数示例
def calc_factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * calc_factorial(x-1))
num = 4
print("The factorial of", num, "is", calc_factorial(num))
上面的例子,calc\u factorial()
是一个调用自身的递归函数
当我们用一个正整数调用这个函数时,它将通过减少这个数递归地调用自己
每个函数调用将数字乘以数字的阶乘1,直到数字等于1。这个递归调用可以在以下步骤中解释
calc_factorial(4) # 1st call with 4
4 * calc_factorial(3) # 2nd call with 3
4 * 3 * calc_factorial(2) # 3rd call with 2
4 * 3 * 2 * calc_factorial(1) # 4th call with 1
4 * 3 * 2 * 1 # return from 4th call as number=1
4 * 3 * 2 # return from 3rd call
4 * 6 # return from 2nd call
24 # return from 1st call
当数字减少到1时,我们的递归结束。这称为基本条件
每个递归函数必须有一个停止递归的基本条件,否则函数将无限地调用自身
另一个例子
递归函数通常有两个组件:
- 基本情况是确定递归函数何时停止的条件
- 对自己的呼唤 以下是演示这两个组件的示例:
0
,即我们必须打印多少剩余的“hi”字符串。该函数只返回
在print语句之后,我们再次调用hi\u recursive
,但剩余值减少。这很重要!如果我们不减少剩余值,函数将无限期运行。通常,当递归函数调用自身时,参数会更改为更接近基本情况
让我们想象一下当我们调用hi\u recursive(3)时它是如何工作的:
在函数打印“
hi
”之后,它会使用一个较低的值调用自身,以便在达到0
之前保持该值。在0处,函数返回到在
中调用它的位置,返回到在
一件非常有用的事情就是不要重复递归!在第二次打印中,您执行了
n*recursive(n-1)
,这实际上调用了相同的方法,并将输出搞砸了!而是保存结果并打印/返回:res=n*递归(n-1);打印(f“递归结果{res}”);return res
(你的问题是什么?问“为什么这样做”并没有问任何问题,真的。这就是它所做的。你不明白什么?”urban,你是对的,我完全弄糊涂了。谢谢你的建议。更新答案(sry忘了删除重复呼叫!)您的第一个示例仍然具有对递归的双重调用
def calc_factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * calc_factorial(x-1))
num = 4
print("The factorial of", num, "is", calc_factorial(num))
calc_factorial(4) # 1st call with 4
4 * calc_factorial(3) # 2nd call with 3
4 * 3 * calc_factorial(2) # 3rd call with 2
4 * 3 * 2 * calc_factorial(1) # 4th call with 1
4 * 3 * 2 * 1 # return from 4th call as number=1
4 * 3 * 2 # return from 3rd call
4 * 6 # return from 2nd call
24 # return from 1st call
# Assume that remaining is a positive integer
def hi_recursive(remaining):
# The base case
if remaining == 0:
return
print('hi')
# Call to function, with a reduced remaining count
hi_recursive(remaining - 1)