在Python中不使用全局变量来跟踪递归调用的数量

时间:2013-01-25 01:06:26

标签: python recursion

如何在不使用Python中的全局变量的情况下跟踪递归调用的数量。例如,如何修改以下函数以跟踪调用次数?

def f(n):
    if n == 1:
        return 1
    else:
        return n * f(n-1)

print f(5)

5 个答案:

答案 0 :(得分:10)

这是一个不使用全局的巧妙技巧:你可以在函数本身中存储计数器。

def f(n):
    f.count += 1
    if n == 1:
        return 1
    else:
        return n * f(n-1)

之后:

>>> f.count = 0 # initialize the counter
>>> f(5)
120
>>> f.count
5
>>> f(30)
265252859812191058636308480000000L
>>> f.count
35

无论如何,它处理“所有通话”的情况。

答案 1 :(得分:6)

正如德尔南所说,如果你想要所有的电话永远,那么没有全球性的话就不可能,所以我假设你只是想要电话深度,你只需要需要添加返回值

def f(n):
    if n == 1:
        return 1,0
    else:
        x, call_depth= f(n-1)
        return n * x, call_depth+1

如果您正在处理多个递归调用,您可以执行max(call_depth1, call_depth2)(深度最长的调用树)或只将两者相加(实际调用的总数)

答案 2 :(得分:6)

此方法将为您提供函数运行的次数:

def f(n):
    if hasattr(f,"count"):
        f.count += 1
    else:
        f.count = 1
    if n == 1:
        return 1
    else:
        return n * f(n-1)

答案 3 :(得分:3)

这是一种使用堆栈而不是全局变量的方法。如图所示,它统计了函数的调用次数,包括初始函数,而不仅仅是函数对自身的递归调用次数。要做到这一点,只需将ncalls += 1移到else语句的开头。

def f(n, ncalls=0):
    ncalls += 1
    if n == 1:
        return 1, ncalls
    else:
        res, ncalls = f(n-1, ncalls)
        return n * res, ncalls

for n in xrange(1, 6):
    print 'f({}): {:4d} ({} calls)'.format(n, *f(n))

输出:

f(1):    1 (1 calls)
f(2):    2 (2 calls)
f(3):    6 (3 calls)
f(4):   24 (4 calls)
f(5):  120 (5 calls)

答案 4 :(得分:0)

你可以添加一个参数来保持调用的计数(需要是可变的),它在函数的开头递增。