[英]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_scope
中l
的 id 与main
的 id 相同。 一旦[3, 4, 5]
被分配,它就会改变,但在main
保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.