答案 0 :(得分:343)
答案 1 :(得分:97)
答案 2 :(得分:42)
答案 3 :(得分:17)
答案 4 :(得分:10)
我意识到这是一个老问题但是对于那些阅读,我建议不要使用递归来解决这个问题 - 列表要快得多并且完全避免递归。我会将其实现为:
def fibonacci(n):
f = [0,1,1]
for i in xrange(3,n):
f.append(f[i-1] + f[i-2])
return 'The %.0fth fibonacci number is: %.0f' % (n,f[-1])
(如果你从0开始计算你的斐波那契序列而不是1,则在xrange中使用n + 1.)
答案 5 :(得分:9)
当然,通过应用Binet公式,可以在O(n)中计算斐波纳契数:
from math import floor, sqrt
def fib(n):
return int(floor(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5))+0.5))
评论者指出,由于2**n
,它不是O(1)而是O(n)。另外一个区别是您只获得一个值,而使用递归时,您获得的所有值Fibonacci(n)
都达到该值。
答案 6 :(得分:9)
如果您经常需要更改递归限制(例如在解决编程谜题时),您可以像这样定义一个简单的context manager:
import sys
class recursionlimit:
def __init__(self, limit):
self.limit = limit
self.old_limit = sys.getrecursionlimit()
def __enter__(self):
sys.setrecursionlimit(self.limit)
def __exit__(self, type, value, tb):
sys.setrecursionlimit(self.old_limit)
然后调用具有自定义限制的函数:
with recursionlimit(1500):
print(fib(1000, 0))
从with
语句的正文退出时,递归限制将恢复为默认值。
答案 7 :(得分:6)
我遇到了类似的错误“超出最大递归深度”的问题。我发现错误是由我用os.walk循环的目录中的损坏文件触发的。如果您在解决此问题时遇到问题并且正在使用文件路径,请务必将其缩小范围,因为它可能是一个损坏的文件。
答案 8 :(得分:6)
resource.setrlimit
也必须用于增加堆栈大小并防止段错误
Linux内核限制了进程堆栈。
Python将局部变量存储在解释器的堆栈中,因此递归会占用解释器的堆栈空间。
如果Python解释器试图超过堆栈限制,那么Linux内核会对其进行分段。
堆栈限制大小由getrlimit
和setrlimit
系统调用控制。
Python通过resource
模块提供对这些系统调用的访问。
import resource
import sys
print resource.getrlimit(resource.RLIMIT_STACK)
print sys.getrecursionlimit()
print
# Will segfault without this line.
resource.setrlimit(resource.RLIMIT_STACK, [0x10000000, resource.RLIM_INFINITY])
sys.setrecursionlimit(0x100000)
def f(i):
print i
sys.stdout.flush()
f(i + 1)
f(0)
当然,如果你继续增加ulimit,你的RAM将耗尽,这会因为交换疯狂而导致计算机停止运行,或者通过OOM Killer杀死Python。
从bash中,您可以看到并设置堆栈限制(以kb为单位):
ulimit -s
ulimit -s 10000
我的默认值是8Mb。
另见:
在Ubuntu 16.10,Python 2.7.12。
上测试答案 9 :(得分:4)
使用发电机?
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fibs = fib() #seems to be the only way to get the following line to work is to
#assign the infinite generator to a variable
f = [fibs.next() for x in xrange(1001)]
for num in f:
print num
上面的fib()函数改编自:http://intermediatepythonista.com/python-generators
答案 10 :(得分:4)
如果您只想获得少量Fibonacci数字,可以使用矩阵方法。
from numpy import matrix
def fib(n):
return (matrix('0 1; 1 1', dtype='object') ** n).item(1)
numpy使用快速求幂算法很快。你在O(log n)得到答案。它比Binet的公式更好,因为它只使用整数。但是如果你想要所有斐波纳契数都达到n,那么最好通过记忆来做到这一点。
答案 11 :(得分:2)
许多人建议增加递归限制是一个很好的解决方案,但不是因为总会有限制。而是使用迭代解决方案。
def fib(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
print fib(5)
答案 12 :(得分:1)
作为@alex suggested,您可以使用生成器函数来执行此操作。这是您问题中代码的等价物:
def fib(n):
def fibseq(n):
""" Iteratively return the first n Fibonacci numbers, starting from 0 """
a, b = 0, 1
for _ in xrange(n):
yield a
a, b = b, a + b
return sum(v for v in fibseq(n))
print format(fib(100000), ',d') # -> no recursion depth error
答案 13 :(得分:1)
import sys
sys.setrecursionlimit(1500)
def fib(n, sum):
if n < 1:
return sum
else:
return fib(n-1, sum+n)
c = 998
print(fib(c, 0))
答案 14 :(得分:1)
我想给你一个使用记忆来计算斐波那契的例子,因为这将允许您使用递归来计算更大的数字:
cache = {}
def fib_dp(n):
if n in cache:
return cache[n]
if n == 0: return 0
elif n == 1: return 1
else:
value = fib_dp(n-1) + fib_dp(n-2)
cache[n] = value
return value
print(fib_dp(998))
这仍然是递归的,但是使用了一个简单的哈希表,该哈希表允许重复使用先前计算的斐波那契数,而不是再次进行计算。
答案 15 :(得分:0)
我们可以使用@lru_cache
装饰器和setrecursionlimit()
方法来做到这一点:
import sys
from functools import lru_cache
sys.setrecursionlimit(15000)
@lru_cache(128)
def fib(n: int) -> int:
if n == 0:
return 0
if n == 1:
return 1
return fib(n - 2) + fib(n - 1)
print(fib(14000))
3002468761178461090995494179715025648692747937490792943468375429502230242942284835863402333575216217865811638730389352239181342307756720414619391217798542575996541081060501905302157019002614964717310808809478675602711440361241500732699145834377856326394037071666274321657305320804055307021019793251762830816701587386994888032362232198219843549865275880699612359275125243457132496772854886508703396643365042454333009802006384286859581649296390803003232654898464561589234445139863242606285711591746222880807391057211912655818499798720987302540712067959840802106849776547522247429904618357394771725653253559346195282601285019169360207355179223814857106405285007997547692546378757062999581657867188420995770650565521377874333085963123444258953052751461206977615079511435862879678439081175536265576977106865074099512897235100538241196445815568291377846656352979228098911566675956525644182645608178603837172227838896725425605719942300037650526231486881066037397866942013838296769284745527778439272995067 2314920693691302891547531323138832943985935078735556672110054220032041561548590315294621529531199575971957359536867988711311482550501404508450342400953050944499115785985396588557041582402218095280101794144934995834735688732530679216395139965967382758179096248575936932919808413032911456135664665752332836514201349157649613728759338222629534204445483491804365831832919448755994772408147745801871446379654872505781349904024433656779853884819614924449819945230342456197818533654765527194609607959296668836657042938973102012760116580743591941893596607924960274722264285715479716022598086974414353585784805898377669116842002756368891922547626785125970004526761913744759327966638428657446582649249137716764154041799200960747515164228729976654250474574283272762300592961327227879153001050020190062933200829553787159082636533777550311557940634505157310094024075846831328702063769940259207902985911442136599426686220621914413462000983429439551695225325742716449543602174724585214896718594652325684194041820439 66092211744372699797375966048010775453444600153524772238401414789562651410289808994960533132759532092895779406940925252906166612153699850759933762897947175972147868784008320247586210378556711332739463277940255289047962323306946068381887446046387745247925675240182981190836264964640612069909458682443392729946084099312047752966806439331403663934969942958022237945205992581178803606156982034385347182766573351768749665172549908638337611953199808161937885366709285043276595726484068138091188914698151703122773726725261370542355162118164302728812259192476428938730724109825922331973256105091200551566581350508061922762910078528219869913214146575557249199263634241165352226570749618907050553115468306669184485910269806225894530809823102279231750061652042560772530576713148647858705369649642907780603247428680176236527220826640665659902650188140474762163503557640566711903907798932853656216227739411210513756695569391593763704981001125
答案 16 :(得分:0)
我们还可以使用动态编程自底向上方法的变体
def fib_bottom_up(n):
bottom_up = [None] * (n+1)
bottom_up[0] = 1
bottom_up[1] = 1
for i in range(2, n+1):
bottom_up[i] = bottom_up[i-1] + bottom_up[i-2]
return bottom_up[n]
print(fib_bottom_up(20000))
答案 17 :(得分:0)
我不确定是否要重复某人,但不久前,一个好心人为递归调用函数编写了Y运算符,例如:
def tail_recursive(func):
y_operator = (lambda f: (lambda y: y(y))(lambda x: f(lambda *args: lambda: x(x)(*args))))(func)
def wrap_func_tail(*args):
out = y_operator(*args)
while callable(out): out = out()
return out
return wrap_func_tail
然后递归函数需要形式:
def my_recursive_func(g):
def wrapped(some_arg, acc):
if <condition>: return acc
return g(some_arg, acc)
return wrapped
# and finally you call it in code
(tail_recursive(my_recursive_func))(some_arg, acc)
对于斐波那契数字,您的函数如下所示:
def fib(g):
def wrapped(n_1, n_2, n):
if n == 0: return n_1
return g(n_2, n_1 + n_2, n-1)
return wrapped
print((tail_recursive(fib))(0, 1, 1000000))
输出:
..684684301719893411568996526838242546875
(实际上是数字的色调)
答案 18 :(得分:0)
RecursionError: 比较时超出了最大递归深度
解决方案:
首先最好知道当您在 Python 中对大输入 (> 10^4) 执行递归函数时,您可能会遇到“超出最大递归深度错误”。
Python 中的 sys 模块有一个函数 getrecursionlimit() 可以显示您的 Python 版本中的递归限制。
import sys
print("Python Recursive Limitation = ", sys.getrecursionlimit())
某些版本的 Python 中的默认值为 1000,而在其他一些版本中为 1500
您可以更改此限制,但重要的是要知道如果您增加太多,您将出现内存溢出错误。
所以在增加之前要小心。您可以使用 setrecursionlimit() 在 Python 中增加此限制。
import sys
sys.setrecursionlimit(3000)
请点击此链接以获取有关导致此问题的原因的更多信息: