简体   繁体   English

写一个递归函数来求解斐波那契

[英]Write a recursive function to solve Fibonacci

I want to write a recursive function in Python for Fibonacci.我想用 Python 为斐波那契写一个递归函数。

x will be the starting point, y will be the subsequent of x and l is the length. x将是起点, y将是x的后续点, l是长度。

I don't understand what is my error in thinking:我不明白我的思维错误是什么:

 def fib(x, y, l, fibList=None):
    fibList = []
    z = x + y
    x = y
    fibList.append(z)
    y = z

    if len(fibList) <= l:
        return fib(x, y, l, fibList)
    else:
        return(fibList)

The result is:结果是:

RecursionError: maximum recursion depth exceeded while calling a Python object

I can solve it with a for loop but not with recursive function.我可以用 for 循环解决它,但不能用递归函数解决。

There are a few problems here.这里有几个问题。 Once you fix the infinite recursion, you still have an issue.一旦你修复了无限递归,你仍然有问题。

As @Raqha points out, you need to not initialize your list every time the fib function is called, but rather only the first time, when the fibList parameter isn't supplied and so defaults to None .正如@Raqha 指出的那样,您不需要在每次调用fib函数时初始化您的列表,而只是在第一次未提供fibList参数时初始化您的列表,因此默认为None

Your code is not able to generate the first two numbers in the sequence, 0 and 1 .您的代码无法生成序列中的前两个数字01 You can fix this by simply initializing your list to include these terms, and adjust the logic to only provide N-2 more terms.您可以通过简单地初始化列表以包含这些术语来解决此问题,并调整逻辑以仅提供 N-2 个更多的术语。

The signature of your function could be improved to make it much easier for the caller to use it.可以改进函数的签名,使调用者更容易使用它。 The caller only cares about the number of terms he/she wants.调用者只关心他/她想要的术语数量。 The user shouldn't have to know what to enter for the initial x and y values.用户不必知道为初始xy值输入什么。

Here's a version of your code with the fix for the infinite recursion, the fix for the missing terms, and also with the signature rearranged so that the user can call the function simply and obviously:这是您的代码版本,其中修复了无限递归,修复了缺失项,并且还重新排列了签名,以便用户可以简单明了地调用该函数:

def fib(l, x=0, y=1, fibList=None):
    if fibList is None:
        fibList = [0, 1]
    z = x + y
    x = y
    fibList.append(z)
    y = z

    if len(fibList) < l-1:
        return fib(l, x, y, fibList)
    else:
        return(fibList)

print(fib(10))

Result:结果:

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

At the start of every fib function call you clear your fibList with fibList = [] .在每个fib函数调用开始时,您使用fibList = []清除fibList So the list's length will always be <= 1 , thus you run into an infinite recursion loop which isn't good.因此列表的长度将始终为<= 1 ,因此您会遇到一个不好的无限递归循环。 You need to add something like if fibList is None:您需要添加类似if fibList is None:

When you first call the function "fib" without providing any 4th statement in the argument list, the value of fibList will initially set to "None".当您第一次调用函数“fib”而不在参数列表中提供任何第 4 条语句时,fibList 的值最初将设置为“None”。 But later when you recursively call the function "fib" again, you provide a fibList in the argument list.但是稍后当您再次递归调用函数“fib”时,您在参数列表中提供了一个 fibList。 So the value isnt "None" anymore.所以值不再是“无”。 So when adding an if-statement as mentioned above, the function knows when you call the function from the outside (when you call it in your code as "fib(1,2,10)"), or when the function recursively calls itself.因此,当如上所述添加 if 语句时,该函数知道何时从外部调用该函数(当您在代码中将其称为“fib(1,2,10)”时),或者该函数何时递归调用自身. And so you dont reset the fibList everytime you call the function, but set it only 1 time at the start.因此,每次调用该函数时都不会重置 fibList,而是在开始时仅设置 1 次。

def fib(x, y, l, fibList=None):
    if fibList is None:
        fibList = []
    z = x + y
    ...

On the second line you set fibList = [] .在第二行设置fibList = [] This means that every time you call the function recursively it resets the list to be empty so len(fibList) will always equal 1.这意味着每次递归调用该函数时,它会将列表重置为空,因此len(fibList)将始终等于 1。

Remove that line so the fibList variable is not reset, then it should hit your exit condition correctly.删除该行,以便 fibList 变量不会被重置,然后它应该正确地达到您的退出条件。 How it is written now it runs forever until it breaks.现在它是如何编写的,它会一直运行,直到损坏为止。

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

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