【python3】 图解 斐波那契数列,零基础思路讲解

  • Post author:
  • Post category:python


导读:斐波那契的代码实现思路,更多思路请看其他文章。顺面讲解了普通函数加上field变成生成器。

一、理解斐波那契数列

斐波那契数列的由来,背景介绍:

有个数学家列昂纳多·斐波那契,他突发奇想,想了个问题。

假设有一对兔子,长两个月它们就算长大成年了。然后以后每个月都会生出1对兔子,生下来的兔子也都是长两个月就算成年,然后每个月也都会生出1对兔子了。这里假设兔子不会死,每次都是只生1对兔子。

第一个月,只有1对小兔子;

第二个月,小兔子还没长成年,还是只有1对兔子;

第三个月,兔子长成年了,同时生了1对小兔子,因此有两对兔子;

第四个月,成年兔子又生了1对兔子,加上自己及上月生的小兔子,共有3对兔子;

第五个月,成年兔子又生了1对兔子,第三月生的小兔子现在已经长成年了且生了1对小子,加上本身两只成年兔子及上月生的小兔子,共5对兔子;

这样过了一年之后,会有多少对兔子了呢?

这个就是兔子数列,也就是斐波那契数列。

它的规律是:1、1、2、3、5、8、13、21、34、55、89、144、233

它是怎么算出来的呢。。

由图可以看到,看出规律了吗?? 把两个值相加的结果作为下一次的基础再加前一个的值。图片的箭头,表示替换了位置。

由此,我们的思路有了,设置2个变量,让两个变量相加,再替换。

现在我们思路已经有了对吧! 接下来,是不是只要把这个思路放到循环里面,最后生成就完了。

#从0,1开始计算
def foo():
    a,b = 0,1
    mylist=[]
    for x in range(10):
        mylist.append(b)
        a,b =b,a+b
    print(mylist)
foo()

如果你想直接从1,1开始计算,则是先取a的值。一般我喜欢从0,1开始计算,看个人喜欢啦哈哈

#直接从1,1开始计算也行
def foo():
    a,b = 1,1
    mylist=[]
    for x in range(10):
        mylist.append(a)
        a,b =b,a+b
    print(mylist)
foo()

运行结果:

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

二、用生成器 解题斐波那契

导读:刚生成的列表,如果数据多的话,则很占空间。如果将来要生成十万以上,会boom掉。。有没有方法优化呢

把普通函数变成生成器,用关键字yield

def foo():
    a,b = 0,1

    for x in range(10):
        yield b
        a,b =b,a+b

f=foo()
print(f)
print(next(f))
print(next(f))
print(next(f))

运行结果:

<generator object foo at 0x0000000001199570>

1

1

2

解释:generator object 为生成器对象。yield 关键字做了2件事情,1,返回了一个结果,2,返回结果后暂停

yield 如果不理解,可以测试下就知道了

第一步测试:

def foo():
    a,b = 0,1
    print("----调试1----")
    for x in range(10):
        print("----调试2----")
        yield b
        print("----调试3----")
        a,b =b,a+b
        print("----调试4----")

foo()

运行结果:空的,也就是函数没有执行

第二步测试:

def foo():
    a,b = 0,1
    print("----调试1----")
    for x in range(10):
        print("----调试2----")
        yield b
        print("----调试3----")
        a,b =b,a+b
        print("----调试4----")

print(foo())

运行结果:

<generator object foo at 0x0000000000709620>

第三步测试:

def foo():
    a,b = 0,1
    print("----调试1----")
    for x in range(10):
        print("----调试2----")
        yield b
        print("----调试3----")
        a,b =b,a+b
        print("----调试4----")

f=foo()
print(next(f))

print("————————分割线————————")

print(next(f))

print("————————分割线————————")

print(next(f))

运行结果:

—-调试1—-

—-调试2—-

1

————————分割线————————

—-调试3—-

—-调试4—-

—-调试2—-

1

————————分割线————————

—-调试3—-

—-调试4—-

—-调试2—-

2

总结:

普通函数加了关键字yield后,就变成生成器了

yield b 这句话做了2件事情,1,返回了一个结果,2,返回结果后暂停