Python入门篇-生成器函数

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.生成器概述

1>.生成器generator

  生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象

2>. 生成器函数

  函数体中包含yield语句的函数,返回生成器对象

  生成器对象,是一个可迭代对象,是一个迭代器

  生成器对象,是延迟计算,惰性求值的

  包含yield语句的生成器函数生成生成器对象的时候,生成器函数的函数体不会立即执行

  next(generator)会从函数的当前位置向后执行到之后碰到的第一个yield语句,会弹出值,并暂停函数执行

  再次调用next函数,和上一条一样的处理过程
  
  没有多余的yield语句能被执行,继续调用next函数,会抛出StopIteration异常
  

3>.编写一个生成器函数样例

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com """
关于生成器函数的相关说明: 在生成器函数中,使用多个yield语句,执行一次后会暂停执行,把yield表达式的值返回 再次执行会执行到下一个yield语句 return 语句依然可以终止函数运行,但return语句返回值不能被捕获到 return 会导致无法继续获取下一个值,抛出StopIteration异常 如果函数没有显示的return语句,如果生成器函数执行到结尾,一样会抛出StopIteration异常哟 """
def gen():
print('line 1')
yield 1
print('line 2')
yield 2
print('line 3')
return 3 next(gen()) next(gen()) g = gen() print(next(g))
print(next(g)) # print(next(g)) #报错:StopIteration: 3,因为已经没有多余的yield语句啦,上面已经被调用两次了 print(next(g, 'End')) #如果没有元素就给个缺省值 #以上代码执行结果如下:
line 1
line 1
line 1
1
line 2
2
line 3
End

二.生成器应用

1>.无限循环

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com def counter():
i = 0
while True:
i += 1
yield i def inc(c):
return next(c) c = counter() #这是一个生成器对象 print(inc(c))
print(inc(c)) #以上代码输出结果如下:
1
2

2>.计数器

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com def inc():
def counter():
i = 0
while True:
i += 1
yield i
c = counter()
return lambda : next(c) #这里返回的是匿名函数 foo = inc()
print(foo())
print(foo()) #以上代码输出结果如下:
1
2

3>.处理递归问题

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com def fib():
x = 0
y = 1
while True:
yield y
x, y = y, x+y foo = fib() for _ in range(5):
print(next(foo)) for _ in range(100):
next(foo) print(next(foo)) #以上代码输出结果如下:
1
1
2
3
5
6356306993006846248183
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com pre = 0
cur = 1
print(pre,cur,end=" ") def fib(n,pre=0,cur=1):
pre,cur = cur,pre + cur
print(cur,end=" ")
if n == 2:
return
fib(n-1,pre,cur) fib(106)

以上代码改写成递归方式戳我~

4>.协程(coroutine)

(1)生成器的高级用法

(2)比进程,线程轻量级

(3)是在用户空间调度的一种实现

(4)Python3 asyncio就是协程实现,已经加入到标准库

(5)Python3.5 使用async,await关键字直接原生支持协程
协程调度器实现思路:
有2个生成器A,B
next(A)后,A执行到了yield语句暂停,然后去执行next(B),B执行到yield语句也暂停,然后再次调用next(A),再调用next(B),周而复始,就实现了调度的效果
可以引入调度的策略来实现切换的方式 (6)协程就是一种非抢占式调度

三.yield from

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com def inc():
for x in range(1000):
yield x foo = inc()
print(next(foo))
print(next(foo))
print(next(foo)) print("*" * 20 + "我是分割符" +"*" * 20) """
以上代码可以使用yield from代码改写,等价于下的代码:
"""
def inc():
yield from range(1000) bar = inc()
print(next(bar))
print(next(bar))
print(next(bar)) #以上代码输出结果如下:
0
1
2
********************我是分割符********************
0
1
2
#!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com """
yield from是Python 3.3出现新的语法 yield from iterable 是 for item in iterable: yield item 形式的语法糖 """ #从可迭代对象中一个个拿元素
def counter(n):
for x in range(n):
yield x def inc(n):
yield from counter(n) foo = inc(10)
print(next(foo))
print(next(foo)) #以上代码执行结果如下:
0
1

yield from是Python 3.3出现新的语法

Python入门篇-生成器函数的更多相关文章

  1. Python入门篇-匿名函数

    Python入门篇-匿名函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.匿名函数概述 1>.什么是匿名函数 匿名,即没有名字 匿名函数,即没有名字的函数 2>. ...

  2. Python入门篇-函数、参数及参数解构

    Python入门篇-函数.参数及参数解构 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数概述 1>.函数的作用即分类 函数 数学定义:y=f(x) ,y是x的函数,x ...

  3. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  4. Python入门篇-解析式、生成器

    Python入门篇-解析式.生成器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.列表解析式(List Comprehension) 1>.列表解析式语法 语法 [ 返回 ...

  5. Python入门篇-面向对象概述

    Python入门篇-面向对象概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.语言的分类 面向机器 抽象成机器指令,机器容易理解 代表:汇编语言 面向过程 做一件事情,排出个 ...

  6. Python入门篇-类型注解

    Python入门篇-类型注解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数定义的弊端 1>.动态语言很灵活,但是这种特性也是弊端 Python是动态语言,变量随时可 ...

  7. Python入门篇-内建函数

    Python入门篇-内建函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常见的内建函数案例  1>.标识id 返回对象的唯一标识,CPython返回内存地址. #!/ ...

  8. Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict)

    Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装和结构 #!/usr/bin/env pytho ...

  9. Python入门篇-文件操作

    Python入门篇-文件操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.文件IO常用操作 open:打开 read:读取 write:写入 close:关闭 readlin ...

随机推荐

  1. 转 zabbix 自动发现和 zabbix自定义用户key与参数User parameters

    ########31 https://www.cnblogs.com/yjt1993/p/10883345.html 1.概念 在配置Iterms的过程中,有时候需要对类似的Iterms进行添加,这些 ...

  2. Linux的.a、.so和.o文件 对比 window下的dll,lib,exe文件

    连续几天终于将一个又一个问题解决了,这里说其中一个问题 描述问题:使用多线程pthread的时候,(我用的IDE,CODEBOLCKS)编译后发现直接弹出窗口,程序还没有被Build..巴拉巴拉,然后 ...

  3. axios get,post请求时带headers

    axios post请求时带headers: axios.post("http://xxx.com/xxx/xxx/xxx?", { 'queslistid': this.kemu ...

  4. [PHP] 浅谈 Laravel Authentication 的 auth:api

    auth:api 在 Laravel 的 Routing , Middleware , API Authentication 主题中都有出现. 一. 在 Routing 部分可以知道 auth:api ...

  5. 第2部分 Elasticsearch查询-请求体查询、排序

    一.请求体查询 请求体 search API, 之所以称之为请求体查询(Full-Body Search),因为大部分参数是通过http请求体而非查询字符串来传递的. 请求体查询:不仅可以处理自身的查 ...

  6. [LOJ3053]希望

    对于一组$s_{1\cdots k}$,合法的$u$构成一个连通块,满足$\left\lvert V\right\rvert-\left\lvert E\right\rvert=1$ 考虑算出算$f_ ...

  7. Ajax返回的数据存放到js数组

    js定义数组比较简单: var  array = [ ] ; 即可 今天记录一下 js 数组的常用规则: 1. b = [1,'da',"sdaf"]; //定义数组给数组添加默认 ...

  8. Versioning information could not be retrieved from the NuGet package repository. Please try again later.

    Versioning information could not be retrieved from the NuGet package repository. Please try again la ...

  9. MySQL视图、触发器、事务、存储过程、内置函数、流程控制、索引

    一.视图 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view tea ...

  10. STVD生成hex,bin,显示ram&flash的使用情况

    前言: 虽然stvd免费,但使用起来并不令人满意,不能自动补全,界面丑陋,设置繁琐,最难受的是不会自动输出ram和flash的使用情况.当然方法还是有的,下面就讲讲我是怎么实现的.个人水平有限,如有错 ...