我想用2个参数(步骤,数字)创建一个递归函数。
在递归内发生一些带有数字的操作,并使用步骤1和新的数字再次调用该函数。
steps == 0
一开始我要增加一个计数器,所以我看到遇到了多少个调用步骤0的函数,具体取决于函数中的算法。
有没有办法做到-没有全局变量或其他参数,两者都不可能!
我尝试过:
if not counter in locals():
counter=0
但这不能正常工作
UnboundLocalError: local variable 'counter' referenced before assignment
此处为完整代码:
def IsaacRule(steps, number):
if not counter in locals():
counter = 0
if steps == 0:
counter+=1
return counter
if ((number - 1) / 3) % 2 == 1:
IsaacRule(steps-1, (number - 1) / 3)
if (number * 2) % 2 == 0:
IsaacRule(steps-1, number*2)
return counter
具有全局变量(并且函数外部的counter = 0)可以正常工作-但我不允许使用全局变量
答案 0 :(得分:0)
一种可能的解决方案是使用自定义可调用类型:
class MyRecursiveFunc(object):
def __init__(self):
self.counter = 0
def __call__(self, steps, numbers):
if steps == 0:
self.counter += 1
results = self.do_something(steps, numbers)
if some_condition():
results.extend(self(steps-1, numbers))
return results
func = MyRecursiveFunc()
results = func(steps, numbers)
print(func.counter)
另一种方法是将臭名昭著的“默认可变参数”陷阱变成您的优势:
def IsaacRule(steps, number, _counter=[0]):
if steps == 0:
_counter[0] += 1
else:
if ((number - 1) / 3) % 2 == 1:
IsaacRule(steps-1, (number - 1) / 3)
if (number * 2) % 2 == 0:
IsaacRule(steps-1, number*2)
return _counter[0]
或者如果您唯一关心的结果是计数器,则可以在进行递归调用时更新它:
def IsaacRule(steps, number):
if steps == 0:
return 1
counter = 0
if ((number - 1) / 3) % 2 == 1:
counter += IsaacRule(steps-1, (number - 1) / 3)
if (number * 2) % 2 == 0:
counter += IsaacRule(steps-1, number*2)
return counter
答案 1 :(得分:0)
您可以在函数本身中存储计数器:
def IsaacRule(steps, number):
if steps == 0:
IsaacRule.counter+=1
return IsaacRule.counter
if ((number - 1) / 3) % 2 == 1:
IsaacRule(steps-1, (number - 1) / 3)
if (number * 2) % 2 == 0:
IsaacRule(steps-1, number*2)
return IsaacRule.counter
IsaacRule.counter = 0
print(IsaacRule(10, 1000))