Python递归仅在必要时计算
假设我有两个功能:Python递归仅在必要时计算,python,python-3.x,Python,Python 3.x,假设我有两个功能: def s(x,y,z): if x <= 0: return y return z def f(a,b): return s(b, a+1, f(a,b-1)+1) 我从不计算f(5,-1),因为它是不需要的。s函数将返回6,因为参数x为零,因此不需要计算参数z 但是,如果我尝试在python中运行它,它将一直递归,或者直到我得到最大递归深度错误,大概是因为python希望在执行s函数之前计算所有参数 我的问题是,我将如何实现这些
def s(x,y,z):
if x <= 0:
return y
return z
def f(a,b):
return s(b, a+1, f(a,b-1)+1)
我从不计算f(5,-1)
,因为它是不需要的。s
函数将返回6,因为参数x
为零,因此不需要计算参数z
但是,如果我尝试在python中运行它,它将一直递归,或者直到我得到最大递归深度错误,大概是因为python希望在执行s
函数之前计算所有参数
我的问题是,我将如何实现这些函数或任何类似的场景,从而在不再需要递归时停止递归?是否可以延迟每个参数的求值,直到它在函数中使用?调用函数时,所有参数在传递给函数之前都会被完全求值。换句话说,
f(5,-1)
在s
启动之前执行
幸运的是,有一种按需计算表达式的简单方法:函数。不要将f(a,b-1)
的结果传递给z
,而是传递一个计算该结果的函数:
def s(x,y,z):
if x <= 0:
return y
return z() # z is a function now
def f(a,b):
return s(b, a+1, lambda:f(a,b-1)+1)
print(f(5,2)) # output: 8
defs(x,y,z):
如果x你的大脑正在处理s()
如何工作的“内部知识”。Python不能,因此它只能遵循严格的规则,即在调用之前必须对调用的所有参数表达式求值
Python是一种高度动态的语言,在执行的每个步骤中,s
和f
都可以反弹到不同的对象。这意味着Python无法优化递归或内联函数逻辑。如果x Python不知道每次执行函数体时将绑定什么f()
,它就不能提升,因为其他代码可以自由地重新绑定f()
。因此Python无法优化这一点,因为它是一种动态语言。因此,如果作为程序员,您知道在b@MartijnPieters时不需要进行额外的f()
递归调用,这是有意义的,但需要我合并s()
和f()
的逻辑,我希望避免这种情况。这就是为什么我把它们分成了不同的功能。我很想听听我的答案有什么不好的地方,值得投反对票。这样我可以改进我的答案!我接受这个答案是为了解释为什么python被设计成这样,这正是我希望得到的一种简洁的解决方法。
def s(x,y,z):
if x <= 0:
return y
return z() # z is a function now
def f(a,b):
return s(b, a+1, lambda:f(a,b-1)+1)
print(f(5,2)) # output: 8
def f(a, b):
if b <= 0:
return a + 1
return f(a, b - 1) + 1
def s(x, y, z):
if x <= 0:
return y
return z() # evaluate the value for z late
def f(a, b):
# make the third argument a function so it is not evaluated until called
return s(b, a+1, lambda: f(a, b - 1) + 1)