如何解决如何跟踪带有返回函数的递归函数
我正在尝试跟踪这个递归函数,但是我尝试了我通常做的事情,但是当您返回需要向其添加某些内容的函数时,它不起作用。有人可以向我解释一下,让我更好地了解如何使用以下代码中的表(或任何其他方法)跟踪这样的函数:
def NumberPatern(Value1,Value2,EndValue):
print(Value1)
if Value1<= EndValue:
temp = Value2
Value2 = Value1
Value1 = Value1 + temp
return NumberPatern(Value1,EndValue)+1
else:
return 0
使用它作为函数的输入
NumberPatern(1,1,12)
我也得到了这张表来跟踪函数:
解决方法
将函数的结果赋值给一个变量。然后你可以在返回之前打印表的所有列。
def NumberPatern(Value1,Value2,EndValue):
if Value1<= EndValue:
temp = Value2
Value2 = Value1
Value1 = Value1 + temp
output = NumberPatern(Value1,EndValue)+1
else:
temp = 'N/A'
output = 0
print(Value1,temp,EndValue,output)
return output
,
假设您是计算机,逐行解释此函数。
每次调用函数时,在表中的新行中记录调用它的“Value1”、“Value2”和“EndValue”。
每次分配 temp
时都填写“Temp”列。
只要程序产生输出(即调用 print()
。
当您点击 return
语句时,填写“RETURN”列,并提升一个级别。
例如:
第一步:第一次调用函数值1 | Value2 | 温度 | EndValue | 输出 | 返回值 |
---|---|---|---|---|---|
1 | 1 | 12 |
值1 | Value2 | 温度 | EndValue | 输出 | 返回值 |
---|---|---|---|---|---|
1 | 1 | 1 | 12 | 1 |
值1 | Value2 | 温度 | EndValue | 输出 | 返回值 |
---|---|---|---|---|---|
1 | 1 | 1 | 12 | 1 | |
2 | 1 | 12 |
temp
从来没有在基本情况下赋值,所以留空)
值1 | Value2 | 温度 | EndValue | 输出 | 返回值 |
---|---|---|---|---|---|
1 | 1 | 1 | 12 | 1 | |
2 | 1 | 1 | 12 | 2 | |
3 | 2 | 2 | 12 | 3 | |
5 | 3 | 3 | 12 | 5 | |
8 | 5 | 5 | 12 | 8 | |
13 | 8 | 12 | 13 | 0 |
值1 | Value2 | 温度 | EndValue | 输出 | 返回值 |
---|---|---|---|---|---|
1 | 1 | 1 | 12 | 1 | 5 |
2 | 1 | 1 | 12 | 2 | 4 |
3 | 2 | 2 | 12 | 3 | 3 |
5 | 3 | 3 | 12 | 5 | 2 |
8 | 5 | 5 | 12 | 8 | 1 |
13 | 8 | 12 | 13 | 0 |
这是完成的桌子。
,代数
现在是回顾代数学习的好时机
def NumberPatern(Value1,EndValue):
print(Value1)
if Value1<= EndValue:
temp = Value2
Value2 = Value1
Value1 = Value1 + temp
# focus here
return NumberPatern(Value1,EndValue)+1
else:
return 0
这个问题的难点在于 Value1
和 Value2
被重新分配。但是我们可以用一种不那么令人困惑的方式重写它。
首先用它的值替换 Value1
-
temp = Value2
Value2 = Value1
# Value1 = Value1 + temp
return NumberPatern(Value1 + temp,EndValue)+1
现在用它的值替换 Value2
-
temp = Value2
# Value2 = Value1
# Value1 = Value1 + temp
return NumberPatern(Value1 + temp,Value1,EndValue)+1
最后用它的值替换 temp
-
# temp = Value2
# Value2 = Value1
# Value1 = Value1 + temp
return NumberPatern(Value1 + Value2,Value1,EndValue)+1
现在让我们看看我们修改后的程序。我们将在每一步打印 each Value1
、Value2
和 EndValue
-
def NumberPatern(Value1,EndValue):
print(f"v1:{Value1} v2:{Value2} end:{EndValue}")
if Value1 <= EndValue:
# temp = Value2
# Value2 = Value1
# Value1 = Value1 + temp
return NumberPatern(Value1 + Value2,EndValue)+1
else:
return 0
print(NumberPatern(1,1,12))
v1:1 v2:1 end:12
v1:2 v2:1 end:12
v1:3 v2:2 end:12
v1:5 v2:3 end:12
v1:8 v2:5 end:12
v1:13 v2:8 end:12
5 # <- final answer
这可能不是您的作业要求的确切输出,但希望它向您展示了递归函数中使用的变量重新分配所引起的麻烦。输出与格林的答案相同,但删除了重复值。
跟踪装饰器
在我刚刚写的 another Q&A 中,我创建了一个简单的 @trace
装饰器,可以与任何函数一起使用。这个装饰器让我们可以将复杂函数的评估可视化 -
from functools import wraps
def trace(f):
frame = 0
@wraps(f)
def wrapper(*args):
nonlocal frame
space = " "*2*frame
argstring = ",".join(map(str,args))
print(f"{space}-> [frame:{frame}] {f.__name__}({argstring})")
frame = frame + 1
result = f(*args)
frame = frame - 1
print(f"{space}<- [frame:{frame}]",result)
return result
return wrapper
我们可以将它与您的 NumberPatern
函数一起使用,只需在上面的行中写上 @trace
。请注意,我还注释掉了您的内部 print
语句 -
@trace
def NumberPatern(Value1,EndValue):
# print(Value1) # <-
if Value1<= EndValue:
temp = Value2
Value2 = Value1
Value1 = Value1 + temp
return NumberPatern(Value1,EndValue)+1
else:
return 0
现在,当我们运行该函数时,我们可以看到“跟踪”的输出 -
print(NumberPatern(1,12))
-> [frame:0] NumberPatern(1,12)
-> [frame:1] NumberPatern(2,12)
-> [frame:2] NumberPatern(3,2,12)
-> [frame:3] NumberPatern(5,3,12)
-> [frame:4] NumberPatern(8,5,12)
-> [frame:5] NumberPatern(13,8,12)
<- [frame:5] 0
<- [frame:4] 1
<- [frame:3] 2
<- [frame:2] 3
<- [frame:1] 4
<- [frame:0] 5
5
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。