Python:清理我的列表以便重用(斐波纳契示例)

时间:2015-11-13 13:13:27

标签: python list recursion pass-by-reference

所以我试图证明产生斐波那契数的递归方法是非常低效的,我使用列表导致它们被引用调用,因此一旦函数拆分它们仍然会改变相同的变量。问题:我们不知道如何在我们完成后清理清单。这导致了这样的问题:在第一次运行我们的列表时,需要通过1到5,但是从第2次开始运行从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: 如果有人有解决方案,我不需要两个功能,请告诉我们^ _ ^

1 个答案:

答案 0 :(得分:1)

我相信@ jonrsharpe的建议会解决你原来的问题:

def fiborec(n, i=None):
    if i is None:
        i = [1]
    else:
        i.append(len(i) + 1)
    print('this is call nr.:', i[-1])

    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fiborec(n - 1, i) + fiborec(n - 2, i)

fiborec(10)

生成
('this is call nr.:', 1)
('this is call nr.:', 2)
('this is call nr.:', 3)
('this is call nr.:', 4)
('this is call nr.:', 5)
...
('this is call nr.:', 173)
('this is call nr.:', 174)
('this is call nr.:', 175)
('this is call nr.:', 176)
('this is call nr.:', 177)
55

但是可以再次调用(没有第二个参数)而没有副作用。

但是,如果你确实:

  

试图表明产生斐波那契数的递归方法   是非常低效的

公平竞争并使用有效的递归斐波纳契解决方案:

def fibofast(n, res=0, nxt=1, i=None):
    if i is None:
        i = [1]
    else:
        i.append(len(i) + 1)
    print('this is call nr.:', i[-1])

    if n == 0:
        return res
    return fibofast(n - 1, nxt, res + nxt, i)

fibofast(10)

生成
('this is call nr.:', 1)
('this is call nr.:', 2)
('this is call nr.:', 3)
('this is call nr.:', 4)
('this is call nr.:', 5)
('this is call nr.:', 6)
('this is call nr.:', 7)
('this is call nr.:', 8)
('this is call nr.:', 9)
('this is call nr.:', 10)
('this is call nr.:', 11)
55