斐波拉契数列python写法


斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)

第一种:递推方法

递推法,就是递增法,时间复杂度是 O(n),呈线性增长,如果数据量巨大,速度会越拖越慢

  • for循环
def fib(n):
    if n < 0:
        raise IndexError('Index out of range')
    a, b = 0, 1
    for _ in range(n):  # 这里for遍历的时候元素不重要也不需要,所以写的_
        a, b = b, a + b
    return a

测试是否实现基本功能

for i in range(9):
    print(fib(i),end='\t')

C:\Users\zhuzhupoo\AppData\Local\Programs\Python\Python39\python.exe "D:/PyCharm 2021.3.3/py/feibolaqie.py"
0	1	1	2	3	5	8	13	21	
Process finished with exit code 0
print(fib(-1))

C:\Users\zhuzhupoo\AppData\Local\Programs\Python\Python39\python.exe "D:/PyCharm 2021.3.3/py/feibolaqie.py"
Traceback (most recent call last):
  File "D:\PyCharm 2021.3.3\py\feibolaqie.py", line 29, in <module>
    print(fib(-1))
  File "D:\PyCharm 2021.3.3\py\feibolaqie.py", line 12, in fib
    raise IndexError('Index out of range')
IndexError: Index out of range

Process finished with exit code 1
  • while循环
def fib(n):
    if n < 0:
        raise IndexError('Index out of range')
    a, b = 0, 1
    while n > 0:
        a, b = b, a + b
        n -= 1
    return a

功能测试与for的测试一致

第二种:递归方式

def fib(n):
    if n < 0:
        raise IndexError('Index out of range')
    elif n == 0:
        return 0
    elif n < 3:
        return 1
    return fib(n-1) + fib(n-2)

这种方法最简洁,甚至可以转化为单行代码,但是效率最低,会出现大量的重复计算

def fib(n): return 1 if  n < 3 else fib(n-1) + fib(n-2)

由于有大量重复计算,我们可以稍微优化一下,设置一下缓存

from functools import lru_cache

@lru_cache
def fib(n): 
	return 1 if  n < 3 else fib(n-1) + fib(n-2)

第三种:用一个类写出比较全面的斐波拉契

class Fib:
    """一个方便调用的斐波拉契数列"""
    def __init__(self):
        self.items = [0, 1, 1]  # 定义斐波拉契数列前3项(0,1,2)

    def __str__(self):  # 提供可视化输出
        return str(self.items)
    # def __repr__(self):
    #     return self.__str__()
    __repr__ = __str__  # 提供不同情况下的可视化输出,简化上面的代码

    def __len__(self):  # 提供长度方法
        return len(self.items)  # 取列表的长度

    def __iter__(self):
        # return iter(self.items) # 转化为一个生成器,与下面一行代码同功能
        yield from self.items

    def __getitem__(self, index):   # 提供索引方法
        if index < 0:
            raise IndexError('Index out of range')  # 索引为负数抛出异常
        for i in range(len(self), index+1):         # 计算列表中不包含的项
            self.items.append(self.items[i-1] + self.items[i-2])
        return self.items[index]

    # def __call__(self, index):
    #     return self.__getitem__(index)    # 提供实例调用方法,与下面一行代码功能一致,实际上都是将call丢给getitem处理
    #     return self[index]
    __call__ = __getitem__      # 简化上面的代码

测试是否实现基本功能

f = Fib()	# 实例化
print(f)	# 观察可视化是否实现
print(f[0], f[1], f[3],end='\t')	# 观察能否使用实例索引
print(f(0), f(1), f(5),end='\t')	# 观察实例能否调用
for i in range(9):
    print(f(i),end='\t')
for x in f:							# 打印列表中现有的项
    print(x,end='\t')
print(f)


C:\Users\zhuzhupoo\AppData\Local\Programs\Python\Python39\python.exe "D:/PyCharm 2021.3.3/py/fib0130.py"
[0, 1, 1]
0 1 2	0 1 5	0	1	1	2	3	5	8	13	21	0	1	1	2	3	5	8	13	21	[0, 1, 1, 2, 3, 5, 8, 13, 21]
Process finished with exit code 0
print(f[-1])

C:\Users\zhuzhupoo\AppData\Local\Programs\Python\Python39\python.exe "D:/PyCharm 2021.3.3/py/fib0130.py"
Traceback (most recent call last):
  File "D:\PyCharm 2021.3.3\py\fib0130.py", line 36, in <module>
    print(f[-1])
  File "D:\PyCharm 2021.3.3\py\fib0130.py", line 21, in __getitem__
    raise IndexError('Index out of range')  # 索引为负数抛出异常
IndexError: Index out of range

Process finished with exit code 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值