if / else递归函数的返回值不正确但打印值正确

时间:2015-01-25 20:15:00

标签: python if-statement recursion return

尝试使用递归来求解黎曼和。

def f(x):
    import math
    return 10*math.e**(math.log(0.5)/5.27 * x)

liTotal = 0
def radExpo(start, stop, step):
    global liTotal
    x = start
    area = f(x)*step
    liTotal += area
    numOfRects = (stop - start) / step
    if start > (stop - (2 *step)):
        return liTotal
    else:
        return radExpo((start+step), stop, step)

radExpo(12, 16, 1)

如果我将return语句更改为

print liTotal

或者如果我用

调用该函数
print radExpo

它工作正常但是如果我经常调用/返回它会返回错误的值,所以我不能使用返回的内容。

2 个答案:

答案 0 :(得分:0)

如果这是一个关于代码有什么问题的问题,我会重构代码以删除全局引用,它将提高其可靠性。我无法在print liTotal与[{1}}

不同的情况下重新创建您的问题

删除全局变量引用的代码的修改版本如下所示:

print radExpo(12,16,1)

答案 1 :(得分:0)

一些简化:

from math import e, log

# rule #1:
# e ** (a*b) == (e ** a) ** b

# applying rule #1 twice:
# e ** (log(0.5) / 5.27 * x) == ((e ** log(0.5)) ** (1/5.27)) ** x

# rule #2:
# e ** log(k) == k

# applying rule #2:
# e ** log(0.5) == 0.5
# 0.5 ** (1/5.27) == 0.8767556206241964

# so we get:
def fn(x):
    return 10 * 0.8767556206241964 ** x

然后radExpo基本上做尾递归(在函数结束时调用一次),所以我们可以非递归地重写它:

def integrate(fn, start, stop, step):
    steps = int((stop - start) / step)
    return sum(
        fn(start + k*step)     # calculate x directly for each step
        for k in range(steps)  #   to prevent error accumulation
    ) * step

这消除了导致问题的全局变量(因为在再次调用函数之前没有重置它)。

然后

>>> integrate(fn, 12, 16, 1)
6.848645835538626

作为奖励,您可以整合您喜欢的任何功能:

>>> from math import pi, sin
>>> integrate(sin, 0, pi, 0.001)
1.999999361387437    # pretty darn close to 2.0