斐波那契数列
提问
- 指定一个数值n,返回斐波那契数列中的前n项,如 6 返回[1, 1, 2, 3, 5, 8]
- 指定一个数值n,返回斐波那契数列中比n小的所有值, 如10 返回 [1, 1, 2, 3, 5, 8]
思考
对于问题一,我们可以只需要实现一个生成斐波那契数列的迭代器
对于问题二,我们可以修改下问题一的迭代器,新增判断条件就可以
实现
def fib(n, max_num=float('inf')):
a, b = 0, 1
while True:
a, b = b, a + b
if a > max_num or n == 0: break
yield a
n -= 1
assert list(fib(5)) == [1, 1, 2, 3, 5]
assert list(fib(-1, 10)) == [1, 1, 2, 3, 5, 8]
原理
斐波那契数列的前两项n1,n2是1,从第三项n3开始,n3 = n1 + n2
因此只需要记住前两项的,便能推导出后面的项
而问题二又新增了一个最大值,Python中float('inf')表示的是正无穷
因此新增一个判断即可
被淘汰的版本
from itertools import takewhile, cycle
from typing import Iterator
def fib(n):
a, b = 0, 1
if isinstance(n, Iterator):
l = n
else:
assert isinstance(n, int) and n >= 1
l = range(n)
for _ in l:
a, b = b, a + b
yield a
assert list(fib(5)) == [1, 1, 2, 3, 5]
assert list(takewhile(lambda x: x < 100, fib(cycle([1])))) == [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
利用了takewhile 和 cycle,后来发现更加繁琐了 。。。。。
cycle是循环一个可迭代对象
[print(i) for i in cycle([1, 2, 3])]
# 1
# 2
# 3
# 1
# 2
# 3
# ...
takewhile是将一个可迭代对象迭代到不满足条件为止
assert list(takewhile(lambda x: x < 3, [1, 2, 3, 4, 5, 6])) == [1, 2]
网友评论