知行编程网知行编程网  2022-03-01 10:00 知行编程网 隐藏边栏 |   抢沙发  15 
文章评分 0 次,平均分 0.0

 

      很多同学还是对生成器的用法,感到怀疑,特别是有其他语言基础的同学,一下子很难理解和转换过来,那什么情况下会用到yield,建议是当需要在循环过程中依次处理一个序列中的元素的时候,就应该考虑生成器,其实yield是非常巧妙而且很高效,一旦用习惯了就会事半功倍.

 

 

下面举几个简单的例子,让大家轻松理解生成器的妙用

1

 

九九乘法表

1.九九乘法表应该是耳熟能详的,我们用这个做第一个例子

def <span style="color: #faea29;">table_9_9</span>(<span style="color: #15e096;">max=9</span>):
   n=<span style="color: #6897bb;">1
   </span>while n<=<span style="color: #15e096;">max</span>:
      N=[<span style="color: #faea29;">'{}*{}={}'</span>.format(i<span style="color: #cc7832;">,</span>n<span style="color: #cc7832;">,</span>n*i) for i in <span style="color: #ff6b68;">range</span>(<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span>n+<span style="color: #6897bb;">1</span>)]
      n+=<span style="color: #6897bb;">1
      </span>print N
table_9_9()

打印输出一下:

九九乘法,兔子数列,杨辉三角|用Python生成器的妙解

 

2.这样只能打印,不能保存而且上面还会有一个None(仔细看上面图的最下方)如果想保存状态,需要额外的加一个列表来保存

比如这样:

def <span style="color: #faea29;">table_9_9</span>(<span style="color: #15e096;">max=9</span>):
   n=<span style="color: #6897bb;">1
   </span>L=[]
   while n<=<span style="color: #15e096;">max</span>:
      N=[<span style="color: #faea29;">'{}*{}={}'</span>.format(i<span style="color: #cc7832;">,</span>n<span style="color: #cc7832;">,</span>n*i) for i in <span style="color: #ff6b68;">range</span>(<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span>n+<span style="color: #6897bb;">1</span>)]
      n+=<span style="color: #6897bb;">1
      </span>L.append(N)
   return L
T=table_9_9()
for t in T:
   print t

 

3.但是用生成器就可以很简单的搞定

def <span style="color: #faea29;">table_9_9</span>(<span style="color: #15e096;">max=9</span>):
   n=<span style="color: #6897bb;">1
   </span>while n<=<span style="color: #15e096;">max</span>:
      N=[<span style="color: #faea29;">'{}*{}={}'</span>.format(i<span style="color: #cc7832;">,</span>n<span style="color: #cc7832;">,</span>n*i) for i in <span style="color: #ff6b68;">range</span>(<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span>n+<span style="color: #6897bb;">1</span>)]
      n+=<span style="color: #6897bb;">1
      </span><span style="color: #ff2941;">yield N</span>

大家注意看,用yield来保存N的所有中间状态,代码量小了很多,是不是很简洁

 

T=table_9_9()

for t in T:

print t

>>就可以打印九九乘法表了

 

 

2

 

斐波那契数列

 

1.这是一个非常著名的序列,又称兔子数列,生成这样的序列有很多种方法,有的用循环,有的用递归等很多方法,先看一种简单的方法实现的:

def <span style="color: #faea29;">fab0</span>(<span style="color: #15e096;">max</span>):
   n<span style="color: #cc7832;">,</span>a<span style="color: #cc7832;">,</span>b=<span style="color: #6897bb;">0</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">0</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">1
   </span>fab_list=[]
   while n<<span style="color: #15e096;">max</span>:
      fab_list.append(b)
      a<span style="color: #cc7832;">,</span>b=b<span style="color: #cc7832;">,</span>a+b 
      n+=<span style="color: #6897bb;">1</span>

 

print fab0(<span style="color: #6897bb;">5</span>)
>>[1, 1, 2, 3, 5]

 

2.但是这样做有点麻烦哦

  • 需要有一个列表去存储数据
  • 用return只能返回最后的结果,不能返回序列变化的过程,有没有更简单的方法呢,当然有啦,继续看,该我们的生成器排上用场了

     

     

补充一句:就算你用list来保存,但是会多一些代码,没有yield这么简单高效,而且若你要返回这个列表,保存所有的状态,必须要放在函数的底部,如果是想函数中间对一些状态保存,就无法用return了(因为一旦return就出去了)

 

def <span style="color: #faea29;">fab2</span>(<span style="color: #15e096;">max</span>):
   n<span style="color: #cc7832;">,</span>a<span style="color: #cc7832;">,</span>b=<span style="color: #6897bb;">0</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">0</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">1
   </span>fab_list=[]
   for i in <span style="color: #ff6b68;">range</span>(<span style="color: #15e096;">max</span>):
      fab_list.append(b)
    <span style="color: #ff2941;">  yield fab_list</span>
      a<span style="color: #cc7832;">,</span>b=b<span style="color: #cc7832;">,</span>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]

 

3

 

杨辉三角

1.杨辉三角是一个比较有意思的序列,是我国数学史上的一个伟大成就,下面我们就用生成器去产生这样的序列,很简洁,下面的算法最巧妙在于,构建一个[1,0],[1,1,0]这样的序列,大家可以仔细看一下

 

def <span style="color: #faea29;">triangle</span>(<span style="color: #15e096;">max</span>):
   N=[<span style="color: #6897bb;">1</span>]
   n=<span style="color: #6897bb;">0
   </span>while n <<span style="color: #15e096;">max</span>:
      yield N
      N.append(<span style="color: #6897bb;">0</span>)
      N=[N[i-<span style="color: #6897bb;">1</span>]+N[i] for i in <span style="color: #ff6b68;">range</span>(<span style="color: #ff6b68;">len</span>(N))]
      n+=<span style="color: #6897bb;">1
</span>for t in triangle(<span style="color: #6897bb;">10</span>):
   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框架,数据分析都会很容易上手的.

 


好了Python中的生成器实战讲解就讲到这里啦,是不是觉得蛮好玩的,希望能给初学者一些启发,若有什么不懂的,也可以留言跟我探讨交流.

 

 

下面是我公号赞助商,希望大家帮忙支持一下

公号赞助商100offer

优秀人才不缺工作机会,只缺适合自己的好机会。但是他们往往没有精力从海量机会中找到最适合的那个。100offer 会对平台上的人才和企业进行严格筛选,让「最好的人才」和「最好的公司」相遇。

扫描下方二维码,注册 100offer,谈谈你对下一份工作的期待。一周内,收到 5-10 个满足你要求的好机会!

 

九九乘法,兔子数列,杨辉三角|用Python生成器的妙解


 

欢迎大家关注 菜鸟学Python",更多好玩有趣的Python原创教程,趣味算法,经验技巧,行业动态,尽在菜鸟学Python,一起来学python吧

历史文章

Python里最搞怪的招式是啥 |初探生成器

一道Google的算法题 |Python巧妙破解

如何用Python写一个每分每时每天的定时程序

Python入门原创文章,2016年度大盘点

Google推出Python课堂啦

用Python写个弹球的游戏

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享