【发布时间】:2016-02-15 01:58:43
【问题描述】:
所以我试图证明产生斐波那契数的递归方法非常低效,我使用列表因为它们是通过引用调用的,因此一旦函数拆分,它们仍然会更改相同的变量。问题:完成后我不知道如何清理列表。这导致了一个问题,即在我们的列表中第一次运行时需要从 1 到 5,但在第二次运行时从 6 到 10 开始。
# Iterative method has exactly n repetitions
# let's compare recursive method:
def fiborec(n, i = []):
i.append(len(i)+1)
print('this is call nr.:', len(i))
if n == 0:
return 0
elif(n == 1):
return 1
else:
return fiborec(n - 1, i) + fiborec(n - 2, i)
我也试过了:
def fiborec(n, i = [0]):
i[0] += 1
print('this is call nr.:', i[0])
两种方法都表现出相同的行为 :( 这让我想到,i = [0] 没有被使用,因为引用已经存在。
del i[:] 不起作用,因为我们有两个结束条件,所以没有明确的结束,所以添加它的地方有点不清楚 - 至少对我来说。
所以...我的临时修复:
def fiborec(n):
"""Docstring: returns Fibonacci Number for given Int.
recursive method
"""
i = [0] # we want i to be "passed by reference" due to lots of function calls
# but also to be resetted should we reuse the function
return _fiborecursion(n, i)
我不喜欢它,但这是我现在能想到的最好的 D: 如果有人有我不需要两个功能的解决方案,请告诉我们^_^
【问题讨论】:
-
使用
i=None作为默认值,然后在第一次调用函数时检查if i is None: i = []。这是避免此问题的典型方法 (stackoverflow.com/q/1132941/3001761)。或者将 memoization 实现为装饰器。 -
好吧,我现在决定创建一个运行一次的函数,只是为了重置计数器,然后调用递归函数......在我看来并不漂亮,但我能想到的最好的。不过,我一定会通读链接。 TY
标签: python list recursion pass-by-reference