Python:Fibonacci序列

Python: Fibonacci Sequence

我只是想通过做一些基本的函数来提高我的编程技巧。

我想用fibonacci值填充一个列表,但是我想我的代码给出了所有数字的总和,然后打印出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

print numberlist

fibonaccinumbers = []

for n in numberlist:
    def fib(n):
        a, b = 0, 1
        for i in range(n):
            a, b = b, a + b
        return a
    a = fib(n)
    fibonaccinumbers.append(a)


print a

我哪里做错了?


1
print a

好吧,你打印出最终值。

还有一些关于您的代码的注释:

1
2
3
4
numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

您不需要在那里初始化i,for循环为您完成了这一点。此外,您还可以通过执行以下操作来简化整个块:

1
numberlist = list(range(20))

考虑到您实际上不需要将其作为列表,您根本不需要构造它,但是您可以稍后运行for n in range(20)

然后在循环中反复地重新定义fib函数。您应该在它的外部定义它,然后重新使用它。

另外,当你知道你想要创建一个多个斐波那契数的列表时,只需要存储你计算的所有数就可以了。这样你就不用一遍又一遍地做同样的事情了。您还可以使用生成器函数来简化这一切:

1
2
3
4
5
6
7
8
9
10
11
def fibGenerator():
    a, b = 0, 1
    yield 0
    while True:
        a, b = b, a + b
        yield a

fibonaccinumbers = []
fib = fibGenerator()
for n in range(20):
    fibonaccinumbers.append(next(fib))

您可以使用itertools中的take配方,而不是在一个范围内迭代并在生成器上手动调用next,这样做:

1
fibonaccinumbers = take(20, fibGenerator())

在发电机上

Still not too sure what the generator does however.

生成器是生成返回值序列的python函数。这些值是延迟生成的,这意味着当您请求它时。您只需使用yield而不是return,就可以创建生成器。yield将"返回"一个值并暂停生成器。下次您请求一个值时,生成器将在它停止的地方继续运行。

使用生成器可以创建无限序列。正如您在上面的fibGenerator的定义中看到的,有一个无限的while循环,其中有一个yield。当发电机停止时,它不会挂断,尽管有那个回路。

下面是一个简单的自我解释示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> def example():
    print('begin')
    i = 0
    while True:
        print('Calculating next value')
        yield i
        i += 1

>>> g = example()
>>> next(g)
begin
Calculating next value
0
>>> next(g)
Calculating next value
1
>>> next(g)
Calculating next value
2
>>> next(g)
Calculating next value
3
>>> next(g)
Calculating next value
4

next函数是从iterable请求下一个值的内置函数。iterable是您可以迭代的任何东西(例如for x in iterable: ...),任何生成器也是iterable。


我想我会分享一些塔架:

1
2
3
4
5
6
7
def fib(n, a = 0, b = 1):
    seq = [a,b]
    while len(seq) < n:
        seq += [seq[len(seq)-1] + seq[len(seq)-2]]
    return seq

print(fib(13))

输出为:

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

或:

1
2
#or if you want to make up your own
print(fib(13, 1597, 2584))

输出为:

1
[1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]


本着提高编程技能的精神:您可以使用生成器和itertools.islice()获取第一个n斐波那契数的列表:

1
2
3
4
5
6
7
8
9
10
from itertools import islice

def fib(a=0, b=1):
    yield a
    while True:
        yield b
        a, b = b, a + b

fibonacci_numbers = list(islice(fib(), 20))
print(fibonacci_numbers)

号产量

1
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]


问题在最后一行。我敢肯定,这是一种干扰:你应该打印列表,而不是a

其他一些提示:

1:整个块只是重新创建range返回的列表:

1
2
3
4
numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

分配i = 0也是没有意义的。相反,尝试:

1
numberlist = range(20)

在python 3中,称为list(range(20)),因为range没有创建完整的列表。

2:在循环的每一次循环中重新定义fib函数不会产生问题,但肯定不是必需的。将定义移到外部:)


对不起,我是个白痴。我正在打印"A",这是最后一次迭代计算斐波那契。

我本来应该把清单打印出来的。

该死。。。


斐波那契级数中的第n项是:

enter image description here。哪里氧化镁和氧化镁

使用中的上述标识,可以使用列表理解生成序列:

1
[int(((((1 + math.sqrt(5)) / 2) ** x) - (((1 - math.sqrt(5)) / 2) ** (x))) / math.sqrt(5)) for x in range(n)] //where n is the number of terms in the series


我对它进行了压缩,并将"range"或至少list(range())创建自己的列表这一事实带到了车上:

1
2
3
4
5
6
7
8
9
10
11
numberlist = list(range(20))

def fib(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

fibonaccinumbers = [fib(n) for n in numberlist]

print fibonaccinumbers

它似乎可以工作,打印到第20次迭代的每个斐波那契值。我怎么能在不做一些奇怪的事情的情况下称为‘fib(n)’,比如:

1
a = fib(n)

那是我以前习惯的风格。无论如何,这个程序现在看起来好吗?


为什么不使用列表理解?下面是我如何解决这个问题。我将定义一个函数来计算斐波那契数列的n th ter om,如下所示。

1
2
3
4
5
6
def fibo(n):
    if n<=2:
        return 1
    else:
        res = fibo(n-1) + fibo(n-2)
    return res

然后我将使用列表理解来获得我想要的序列。

1
fib_sequence = [fibo(i) for i in range(n+1)]

1
2
3
4
5
def fibonacci(number):
        numbers = [0, 1]
        while len(numbers) < number:
            numbers[len(numbers):len(numbers)] = [numbers[len(numbers)-2] + numbers[len(numbers)-1]]
        return numbers

每次循环运行时,列表中最后两个值都会相加。当迭代到输入长度时,用每个新的fibonacci值在列表中创建一个新位置。


我刚刚使用了公式和插入值:

1
2
3
4
5
6
7
8
9
10
import math

def Fibs(n):

 for i in range (n):

     Fn=int(((((1+math.sqrt(5))**i) - ((1-math.sqrt(5)) **i))/(2**i) * (math.sqrt(5)))/5)
     print (Fn)

Fibs(int(input())


因为每个斐波那契数都是由所有之前的数生成的,所以从头计算每个数是没有意义的。最好使用收集斐波那契数的列表来计算后面的每一个:

1
2
3
4
5
6
7
8
9
10
11
def FibList(n):
    rc = []
    for i in xrange(n):
        if i < 2:
            rc.append(1)
        else:
            rc.append(rc[i-2] + rc[i-1])

    return rc

print FibList(20)

如果您真的想成为spiffy,可以创建一个计算fibonacci值的生成器函数,并使用它来构建列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def Fib(n):
    n1 = 1
    n2 = 1

    for i in xrange(n):
        if i < 2:
            yield 1
        else:
            n3 = n1 + n2
            n1 = n2
            n2 = n3
            yield n3

fiblist = [x for x in Fib(20)]
print fiblist

在生成器函数中,"yield"关键字返回列表的每个值。其中fiblist使用一种称为"列表理解"的东西来使用生成器构建列表。您也可以在for循环中使用发电机:

1
2
for fnum in Fib(20):
    print fnum