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. Dart入门

    要学Flutter必先学Dart,Dart和Java的语法很像,学过Java的人很快就能入手 Dart下载地址https://dart.dev/get-dart VSCode下载地址https://c ...

  2. python字符串拼接N种姿势

    字符串大家都不陌生,应用比较广泛,强大,总是会给你一些惊喜的数据类型.我们本篇文章主要介绍的就是关于字符串的多种方法的拼接. 第一种:直接通过+号拼接 输出结果: 2.通过 str.join()方法拼 ...

  3. Windows10 下安装 oracle 客户端,安装 plsql 破解并实现汉化

    一,软件准备 1,win10 操作系统 2,oracle_11g_r2 client 这里是 64 位的软件  3, plsql 11.0.6 这里我们下载 64 的,32 位操作系统现在已经很少了, ...

  4. 【MongoDB学习之六】MongoDB集群

    环境 MongoDB 4.0 CentOS 6.5_x64 一.主从复制-Master-Slave这种模式已不再推荐使用了. 二.副本集-Replica Set(用的多)副本集其实一种互为主从的关系, ...

  5. VS2015 控制台cl编译器全局环境变量配置

    Visual C++的cl.exe编译器是微软推出的编译器 为了可以在CMD里使用cl.exe手工执行编译操作 设置环境变量 PATH C:\Program Files (x86)\Microsoft ...

  6. openstack keystone 总结

    1.OpenStack组件 OpenStack是一个开源的云计算管理平台项目,由几个主要的组件组合起来完成具体工作.OpenStack是一个不断发展的系统,在它的发展历程之中,它的组件个数在增加,服务 ...

  7. python 判断一个对象是可迭代对象

    那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断: >>> from collections import Iterable &g ...

  8. 【LOJ502】[LibreOJ β Round] ZQC 的截图 (随机化)

    真的是神仙题目啊-- 题目 LOJ502 官方题解 我认为官方题解比我讲得好. 分析 这是一道蒙特卡洛算法的好题 上面那个奇奇怪怪的词是从官方题解里看到的,意思大概就是随机化算法 -- ? 一句话题意 ...

  9. MySQL ALTER TABLE语法

    先看一下定义(密密麻麻) ALTER TABLE tbl_name [alter_specification [, alter_specification] ...] [partition_optio ...

  10. 在JDBC中实现SQL语句的模糊查询

    在JDBC中实现SQL语句的模糊查询 在大多数情况下我们可以在JDBC中写入sql语句通过占位符的方式来直接查询,但是如果要进行模糊查询,需要转义字符才能够正常查询. sql语句: select * ...