这里利用了多种方式来产生fibonacci队列。涉及到递归,装饰器,迭代器,bottom-up算法,算法复杂度分析,生成器等知识。完整理解这些语句,对理解Python的一些高级用法很有帮助。
产生fabonacci序列的方法
方法一:使用迭代器
# Fib1 is a iterator
class Fib1(object):
def __init__(self,maxlevel):
self.a=0
self.b=1
self.maxlevel = maxlevel
self.level=0
def __iter__(self):
return self
def __next__(self):
if self.level > self.maxlevel:
raise StopIteration
self.a, self.b = self.b, self.a+self.b
self.level += 1
return self.a
def main():
print('_________________Fib1________________')
fib = Fib1(10)
for i in fib:
print(i)
if __name__=='__main__':
main()
方法二:普通函数
## Example: Using looping technique
def Fib6(n):
a,b=1,1
for i in range(n-1):
a,b = b,a+b
return a
def main():
print('_________________Fib6________________')
fib = Fib6(10)
print(fib)
if __name__=='__main__':
main()
方法三:递归调用
单独的递归调用的复杂度是指数的复杂度O(2^(n/2)), 后面利用存储以后复杂度则是O(n)
## Example: Using recursion
#
def Fib5(n):
if n<2:
return n
return Fib5(n-1) + Fib5(n-2)
def main():
print('_________________Fib5________________')
fib = Fib5(10)
print(fib)
if __name__=='__main__':
main()
方法四:使用生成器
## Example 3: Using generators, 这里的生成器带参数
def Fib2(maxlevel):
a=0
b=1
for index in range(maxlevel):
a, b = b, a+b
yield a
# Fib3 is a generator ,这里的生成器不带参数,调用时指定。
def Fib3():
a=0
b=1
while True:
yield b
a,b=b,a+b
def main():
print('_________________Fib2________________')
fib = Fib2(10)
for i in fib:
print(i)
print('_________________Fib3________________')
fib = Fib3()
import itertools
print(list(itertools.islice(fib,0,10)))
if __name__=='__main__':
main()
方法五:使用记忆器
#这个例子会利用存储消除递归,是一种bottom-up的算法
def Fib7(n):
fibresult = {}
for i in range(n):
if i <2:
f = 1
else:
f = fibresult[i-1] + fibresult[i-2]
fibresult[i] = f
return fibresult
print('_________________Fib7________________')
fib = Fib7(10)
print(fib.values())
结果:
_________________Fib7________________
dict_values([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
方法六:使用记忆器修饰
## Example 5: Using memoization as decorator,
#利用类做修饰器
class Memoize:
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, arg):
if arg not in self.memo:
self.memo[arg] = self.fn(arg)
return self.memo[arg]
@Memoize
def Fib8(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
#上面是使用类作为修饰器,下面是使用函数作为修饰器。
#decorator example
def memo(fn):
cache = {}
miss = object()
def wrapper(*args):
result = cache.get(args, miss)
if result is miss:
result = fn(*args)
cache[args] = result
return result
return wrapper
@memo
def Fib4(n):
if n < 2:
return n
return Fib4(n - 1) + Fib4(n - 2)
def main():
print('_________________Fib4________________')
fib = Fib4(10)
print(fib)
print('_________________Fib8________________')
fib = Fib8(10)
print(fib)
if __name__=='__main__':
main()
结果:
_________________Fib4________________
55
_________________Fib8________________
55
完整的源代码如下:
# Fib1 is a iterator
class Fib1(object):
def __init__(self,maxlevel):
self.a=0
self.b=1
self.maxlevel = maxlevel
self.level=0
def __iter__(self):
return self
def __next__(self):
if self.level > self.maxlevel:
raise StopIteration
self.a, self.b = self.b, self.a+self.b
self.level += 1
return self.a
# Fib2 is a generator
def Fib2(maxlevel):
a=0
b=1
for index in range(maxlevel):
a, b = b, a+b
yield a
# Fib3 is a generator
def Fib3():
a=0
b=1
while True:
yield b
a,b=b,a+b
#decorator example ,利用函数做修饰器
def memo(fn):
cache = {}
miss = object()
def wrapper(*args):
result = cache.get(args, miss)
if result is miss:
result = fn(*args)
cache[args] = result
return result
return wrapper
@memo
def Fib4(n):
if n < 2:
return n
return Fib4(n - 1) + Fib4(n - 2)
#利用类做修饰器
class Memoize:
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, arg):
if arg not in self.memo:
self.memo[arg] = self.fn(arg)
return self.memo[arg]
@Memoize
def Fib8(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
#recursive
def Fib5(n):
if n<2:
return n
return Fib5(n-1) + Fib5(n-2)
#这个例子会利用存储消除递归,是一种bottom-up的算法
def Fib7(n):
fibresult = {}
for i in range(n):
if i <2:
f = 1
else:
f = fibresult[i-1] + fibresult[i-2]
fibresult[i] = f
return fibresult
def Fib6(n):
a,b=1,1
for i in range(n-1):
a,b = b,a+b
return a
def main():
print('_________________Fib1________________')
fib = Fib1(15)
for i in fib:
print(i)
print('_________________Fib2________________')
fib = Fib2(10)
for i in fib:
print(i)
print('_________________Fib3________________')
fib = Fib3()
import itertools
print(list(itertools.islice(fib,0,10)))
print('_________________Fib4________________')
fib = Fib4(10)
print(fib)
print('_________________Fib5________________')
fib = Fib5(10)
print(fib)
print('_________________Fib6________________')
fib = Fib6(10)
print(fib)
print('_________________Fib7________________')
fib = Fib7(10)
print(fib.values())
print('_________________Fib8________________')
fib = Fib8(10)
print(fib)
if __name__=='__main__':
main()