嗨我对python很新,并尝试创建一个Fibonacci计算器函数,打印所有值到给定数字,如果输入的数字不在序列中,则它将下一个Fibonacci数字添加到列表中。例如,如果输入10,则应返回[0, 1, 1, 2, 3, 5, 8, 13]
。该函数必须是递归的。这是我目前的代码:
def fibonacci(n):
n = int(n)
# The nested sub_fib function computes the Fibonacci sequence
def sub_fib(n):
if n < 2:
return n
else:
return (sub_fib(n-1) + sub_fib(n-2))
#This aspect of the main fib function applies the condition if the number
# input is not in the sequence then it returns the next value up
fib_seq= [sub_fib(i) for i in range(0,n) if sub_fib(i)<=n]
if fib_seq[-1] < n:
fib_seq.append(fib_seq[-1] + fib_seq[-2])
return fib_seq
else:
return fib_seq
print(fibonacci(input("Input a number to print sequence up to: ")))
我已经设法让它工作,但它非常缓慢(我假设由于递归)无论如何我可以加速它而不会大规模改变程序?
答案 0 :(得分:1)
程序运行缓慢的两个主要原因:
您可以将程序更改为仍然是递归的,但重复工作以计算以前的数字,并从构建列表的那一刻开始停止。
您只需使用以下功能:
def fibon(a,b,n,result):
c = a+b
result.append(c)
if c < n:
fibon(b,c,n,result)
return result
我们用fibon(0,1,n,[])
初始化它。在每次迭代中,它将计算下一个Fibonacci数c = a+b
并将其附加到result
。如果该数字仍然小于c < n
,那么我们需要计算下一个数字,从而执行递归调用。
def fibonacci(n):
n = int(n)
def fibon(a,b,n,result):
c = a+b
result.append(c)
if c < n:
fibon(b,c,n,result)
return result
return fibon(0,1,n,[])
print(fibonacci(input("Input a number to print sequence up to: ")))
答案 1 :(得分:0)
这使用递归但比天真的递归实现快得多
def fib(n):
if n == 1:
return [1]
elif n == 2:
return [1, 1]
else:
sub = fib(n - 1)
return sub + [sub[-1] + sub[-2]]
答案 2 :(得分:0)
以下是一些可以提高速度的示例:
"""
Performance calculation for recursion, memoization, tabulation and generator
fib took: 27.052446
mem_fib took: 0.000134
tabular_fib took: 0.000175
yield_fib took: 0.000033
"""
from timeit import timeit
LOOKUP_SIZE = 100
number = 30
lookup = [None] * LOOKUP_SIZE
def fib(n):
return 1 if n <= 2 else fib(n - 1) + fib(n - 2)
def mem_fib(n):
"""Using memoization."""
if n <= 2:
return 1
if lookup[n] is None:
lookup[n] = mem_fib(n - 1) + mem_fib(n - 2)
return lookup[n]
def tabular_fib(n):
"""Using Tabulation."""
results = [1, 1]
for i in range(2, n):
results.append(results[i - 1] + results[i - 2])
return results[-1]
def yield_fib(n):
"""Using generator."""
a = b = 1
yield a
yield b
while n > 2:
n -= 1
a, b = b, a + b
yield b
for f in [fib, mem_fib, tabular_fib, yield_fib]:
t = timeit(stmt=f"f({number})", number=10, globals=globals())
print(f"{f.__name__} took: {t:.6f}")