九九乘法,兔子数列,杨辉三角|用Python生成器的妙解
很多同学还是对生成器的用法,感到怀疑,特别是有其他语言基础的同学,一下子很难理解和转换过来,那什么情况下会用到yield,建议是当需要在循环过程中依次处理一个序列中的元素的时候,就应该考虑生成器,其实yield是非常巧妙而且很高效,一旦用习惯了就会事半功倍.
下面举几个简单的例子,让大家轻松理解生成器的妙用
一.九九乘法表
1.九九乘法表应该是耳熟能详的,我们用这个做第一个例子
def table_9_9(max=9):
n=1
while n<=max:
N=['{}*{}={}'.format(i,n,n*i) for i in range(1,n+1)]
n+=1
print N
table_9_9()
打印输出一下:

2.这样只能打印,不能保存,而且上面还会有一个None(仔细看上面图的最下方)如果想保存状态,需要额外的加一个列表来保存
比如这样:
def table_9_9(max=9):
n=1
L=[]
while n<=max:
N=['{}*{}={}'.format(i,n,n*i) for i in range(1,n+1)]
n+=1
L.append(N)
return L
T=table_9_9()
for t in T:
print t
3.但是用生成器就可以很简单的搞定
def table_9_9(max=9):
n=1
while n<=max:
N=['{}*{}={}'.format(i,n,n*i) for i in range(1,n+1)]
n+=1
yield N
大家注意看,用yield来保存N的所有中间状态,代码量小了很多,是不是很简洁
T=table_9_9()
for t in T:
print t
就可以打印九九乘法表了
二.斐波那契数列
1.这是一个非常著名的序列,又称兔子数列,生成这样的序列有很多种方法,有的用循环,有的用递归等很多方法,先看一种简单的方法实现的:
def fab0(max):
n,a,b=0,0,1
fab_list=[]
while n<max:
fab_list.append(b)
a,b=b,a+b
n+=1
print fab0(5)
>>[1, 1, 2, 3, 5]
2.但是这样做有点麻烦哦
需要有一个列表去存储数据
用return只能返回最后的结果,不能返回序列变化的过程,有没有更简单的方法呢,当然有啦,继续看,该我们的生成器排上用场了
补充一句:就算你用list来保存,但是会多一些代码,没有yield这么简单高效,而且若你要返回这个列表,保存所有的状态,必须要放在函数的底部,如果是想函数中间对一些状态保存,就无法用return了(因为一旦return就出去了)
def fab2(max):
n,a,b=0,0,1
fab_list=[]
for i in range(max):
fab_list.append(b)
yield fab_list
a,b=b,a+b
for n in fab2(7):
print n
打印输出:
[1]
[1, 1]
[1, 1, 2]
[1, 1, 2, 3]
[1, 1, 2, 3, 5]
[1, 1, 2, 3, 5, 8]
[1, 1, 2, 3, 5, 8, 13]
三.杨辉三角
杨辉三角是一个比较有意思的序列,是我国数学史上的一个伟大成就,下面我们就用生成器去产生这样的序列,很简洁,下面的算法最巧妙在于,构建一个[1,0],[1,1,0]这样的序列,大家可以仔细看一下
def triangle(max):
N=[1]
n=0
while n <max:
yield N
N.append(0)
N=[N[i-1]+N[i] for i in range(len(N))]
n+=1
for t in triangle(10):
print t
打印输出:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
好,看完上面三个小例子希望能让大家对生成器理解更深一些,对于生成器还有一些send(),close()和throw()方法,特别是send()不仅可以传值给yield,还能恢复生成器,大大简化协同程序的实现,后面我找到合适的例子,会展开给大家讲.
其实yield用的比较多是在爬虫里面,有用过爬虫的同学一定知道scrapy框架,里面就会有yield,所以小伙伴们一定要把基础学扎实了,这样无论是学爬虫框架,还是学web框架,数据分析都会很容易上手的.