python 中的第 N 个斐波那契数列
Nth Fibonacci in python
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
if memo[i]==-1:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = []
return fibonaci(n,a)
print(fibo(2))
我是一名Java程序员,正在学习python。该算法使用递归 + 记忆计算第 n 个斐波那契数。我不明白为什么 运行 python 中的程序时会看到此错误“IndexError:列表索引超出范围”。有人可以帮忙吗?非常感谢!
我对你的代码做了一些改动以获得第 n 个斐波那契数。(可能还有其他方法)
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
if memo[i] == -1:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = [-1] * n
return fibonaci(n-1,a)
print(fibo(5))
print(fibo(10))
print(fibo(13))
print(fibo(57))
输出为:-
3
34
144
225851433717
美好的一天,欢迎来到 Python:-)
正如您问题的评论中所建议的,memo[i]==-1 不可能是真的。
我理解你想测试类似“如果斐波那契 (i) 的值尚未被记忆”之类的东西,但是 Python 告诉你索引不存在的方式肯定不是通过返回一些魔法值(如 -1),而是通过引发异常。
在您最喜欢的搜索引擎上查找“EAFP”(请求宽恕比请求许可更容易)可能会告诉您为什么异常不应被理解为错误,在 python。
此外,记忆化最好由字典而不是列表来实现(因为字典允许将值映射到任何可能的键,而不必映射到下一个整数索引值)。
在不对您的程序结构做太多改动的情况下,我建议如下:
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
try:
memo[i]
except KeyError:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = {}
return fibonaci(n,a)
print(fibo(2))
您看到错误是因为您使用 a = []
创建了一个空列表,然后您尝试查看它。您需要创建一个足够长的列表,以便从零索引到 n-1。
也就是说,在 Python 中进行记忆的一种简单方法是使用 functools
中的 cache
函数。此代码为您做记忆:
from functools import cache
@cache
def fib(n):
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)
for n in range(10):
print(f"{fib(n) = }")
在 运行 时间里效率不高,但在程序员时间里它是。
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
if memo[i]==-1:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = []
return fibonaci(n,a)
print(fibo(2))
我是一名Java程序员,正在学习python。该算法使用递归 + 记忆计算第 n 个斐波那契数。我不明白为什么 运行 python 中的程序时会看到此错误“IndexError:列表索引超出范围”。有人可以帮忙吗?非常感谢!
我对你的代码做了一些改动以获得第 n 个斐波那契数。(可能还有其他方法)
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
if memo[i] == -1:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = [-1] * n
return fibonaci(n-1,a)
print(fibo(5))
print(fibo(10))
print(fibo(13))
print(fibo(57))
输出为:-
3
34
144
225851433717
美好的一天,欢迎来到 Python:-)
正如您问题的评论中所建议的,memo[i]==-1 不可能是真的。
我理解你想测试类似“如果斐波那契 (i) 的值尚未被记忆”之类的东西,但是 Python 告诉你索引不存在的方式肯定不是通过返回一些魔法值(如 -1),而是通过引发异常。
在您最喜欢的搜索引擎上查找“EAFP”(请求宽恕比请求许可更容易)可能会告诉您为什么异常不应被理解为错误,在 python。
此外,记忆化最好由字典而不是列表来实现(因为字典允许将值映射到任何可能的键,而不必映射到下一个整数索引值)。
在不对您的程序结构做太多改动的情况下,我建议如下:
def fibonaci(i,memo):
if i == 0 or i == 1:
return i
try:
memo[i]
except KeyError:
memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)
return memo[i]
def fibo(n):
a = {}
return fibonaci(n,a)
print(fibo(2))
您看到错误是因为您使用 a = []
创建了一个空列表,然后您尝试查看它。您需要创建一个足够长的列表,以便从零索引到 n-1。
也就是说,在 Python 中进行记忆的一种简单方法是使用 functools
中的 cache
函数。此代码为您做记忆:
from functools import cache
@cache
def fib(n):
if n <= 1:
return n
else:
return fib(n - 1) + fib(n - 2)
for n in range(10):
print(f"{fib(n) = }")
在 运行 时间里效率不高,但在程序员时间里它是。