繁体   English   中英

为什么我的递归函数更新列表(计算 n 的斐波那契数列)

[英]Why is my recursive function updating a list (calculating fibonacci of n)

我正在尝试学习动态编程。 我已经通过一个例子来说明如何找到输入n的斐波那契数,同时缓存每个“新”调用的结果。

我理解函数递归调用的顺序:fib(5) -> fib(4) -> fib(3) -> fib(2) -> fib(1) -> fib(0) -> fib(1) ) -> fib(2) "Cache found" -> fib(3) "Cache found" for n = 5

我正在努力理解最终的 fib(2) 和 fib(3) 调用如何访问更新的缓存,因为每个调用只返回一个整数,而不是列表,我认为我没有将列表声明为一个全局变量。

我最初希望列表在我的代码中表现得像整数 x,所以欢迎解释这些值是如何传递回来的。

代码:

def fib(n, cache, x):
    print(n, cache)
    print("x: ", x)
    x += 1
    if n == 0 or n == 1:
        return n

    if cache[n] == 0:
        cache[n] = fib(n-1, cache, x) + fib(n-2, cache, x)
    else:
        print("Cache called on", n)

    return cache[n]


def main():
    n = 5
    x = 0
    cache = [0 for _ in range(n+1)]
    print(fib(n, cache, x))
    print(cache)
    print("x: ", x)


if __name__ == "__main__":
    main()

输出:

5 [0, 0, 0, 0, 0, 0]
x:  0
4 [0, 0, 0, 0, 0, 0]
x:  1
3 [0, 0, 0, 0, 0, 0]
x:  2
2 [0, 0, 0, 0, 0, 0]
x:  3
1 [0, 0, 0, 0, 0, 0]
x:  4
0 [0, 0, 0, 0, 0, 0]
x:  4
1 [0, 0, 1, 0, 0, 0]
x:  3
2 [0, 0, 1, 2, 0, 0]
x:  2
Cache called on 2
3 [0, 0, 1, 2, 3, 0]
x:  1
Cache called on 3
5
[0, 0, 1, 2, 3, 5]
x:  0

您传递了cache的原件,而不是副本(新建对象)。 因此, fib每个实例都在使用相同的对象。 一个实例中的更新立即可供其他实例使用。 另请参见此处

在 python 函数中,参数是“passed-by-object”(或pass-by-object-reference)。 这意味着如果您将列表(可变对象)传递给函数,则可以修改列表的元素。 但是,如果您将通过新列表分配列表,则该列表将不会在调用方的范围内更改。

def list_scope(l):
    print(l, "id: ", id(l))
    l = [3, 4,5]
    print(l, "id: ", id(l))

def main():
    l = [1, 2, 3]
    print("id: ", id(l))
    list_scope(l)
    print("id: ", id(l))

main()

输出:

id: 4510275784
[1, 2, 3] id:  4510275784
[3, 4, 5] id:  4509275592
id: 4510275784

分配 list [3, 4, 5]之前list_scopel的 id 与main的 id 相同。 一旦[3, 4, 5]被分配,它就会改变,但在main保持不变。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM