上节内容说到Python的for语句循环本质上就是通过调用Iterable可迭代对象的__iter()__方法获得一个Iterator迭代器对象,然后不断调用Iterator迭代器对象__next()__方法实现的。Iterator迭代器对象则是一个需要实现__iter__()和__next__()两个迭代器协议方法的对象。python中生成器提供了一种方便的方法来实现迭代器协议,而不需要必须实现__iter__()和__next__()两个迭代器协议方法。

生成器的定义方式有两种,一种是调用生成器函数,一种是使用生成器表达式语法。

调用生成器函数

生成器函数是指在函数体中使用yield表达式仅返回结果的函数。yield表达式仅在定义生成器函数时使用,因此只能用在函数定义的主体中。在函数体中使用yield表达式会使该函数成为生成器函数。当生成器函数被调用时,它返回一个称为生成器的迭代器,该迭代器由python自动生成。然后,生成器控制了生成器函数的执行。因为返回的生成器是一个迭代器,所以生成器函数的执行结果也就可以被循环。当生成器的的__next__方法被调用时,生成器函数的函数体内的语句开始执行,执行进行到第一个yield表达式时,立即将yield表达式的结果返回给生成器的调用者,同时将生成器函数内部的状态挂起。即保持生成器函数的执行进度,和生成器函数内的局部状态:包括局部变量的当前绑定,指令指针,内部计算栈和任何异常处理的状态。当生成器的再次调用__next__方法来时,生成器函数恢复执行,并再次执行到yield表达式返回结果再保持状态,直到无法再执行到yield表达式。此时生成器自动抛出StopIteration异常。

我们先定义一个简单生成器函数,函数功能返回数字0-9的平方数

# 生成器函数,功能返回数字0-9的平方数

>>> def squares():

for i in range(10):

yield i**2

# 使用return关键字是普通函数,使用yield关键字函数变成了生成器函数

使用参数g接收调用生成器函数squares的结果,然后分别在shell查看squares和g这两个变量的类型

>>> g = squares()

#查看squares对象类型

>>> squares

#查看g对象类型

>>> g

从上面可以看出变量squares是函数类型,变量g是generator类型对象,generator从字面的理解上就是生成器类型。根据上一节迭代器中提到的知识,从collection模块引入Iterator的抽象基类,验证下generator类型是不是上面说的迭代器类型。

>>> from collections import Iterator

>>> isinstance(g,Iterator)

True

验证成功,说明生成器函数的执行结果确实是生成器,一种特殊的迭代器。

>>> for i in g:

print (i)

0

1

4

9

16

25

36

49

64

81

生成器表达式

除了使用生成器函数可以得到生成器,还可以生成器表达式得到生成器表达式。生成器表达式本身看起来像列表推到, 但不是用方括号而是用圆括号包围起来:

>>> g2 = (x**2 for x in range(10))

>>> g2

at 0x0359AFC0>

>>> t = (1,2,3,4,5)

>>> g3 = (x**2 for x in t)

>>> g3

at 0x007F6180>

验证:

>>> isinstance(g2,Iterator)

True

>>> isinstance(g3,Iterator)

True

使用:

>>> for i in g2:

print(i)

0

1

4

9

16

25

36

49

64

81

>>> for i in g3:

print(i)

1

4

9

16

25

和普通迭代器相比,生成器不单简化了迭代器的定义,还在使用效率上有提升。因为生成器在循环时,生成器函数每次只会返回一个结果,然后保持内部状态,所以生成器占用的内存是很小的。以下两个测试结果,第一个直接抛出MemoryError异常,第二个只能正确计算出结果。

# 全部数据先加载在1个列表上面,内存占用高

>>> s1 = sum([i for i in range(100000000)])

Traceback (most recent call last):

File "", line 1, in

s1 = sum([i for i in range(100000000)])

File "", line 1, in

s1 = sum([i for i in range(100000000)])

MemoryError

# 数据几乎不占内存

>>> s2 = sum((i for i in range(100000000)))

>>> s2

4999999950000000

python生成器 图片分类_Python内置类型(6)——生成器相关推荐

  1. python生成器 图片分类_python批量处理图片图片Python迭代器和生成器介绍

    Python迭代器和生成器介绍迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration ...

  2. python中整数类型的表示需加引导符号_Python内置类型及常见问题

    python的内置数据类型非常丰富,大致可以分为五类:None.数字类型.序列类型.映射类型和集合类型.下面我将分别对他们进行介绍,做个总结以备以后查看.下面的表列出了各个类别下的具体数据类型.*注: ...

  3. python集合中的元素不能是哪些数据类型_Python内置类型及常见问题

    python的内置数据类型非常丰富,大致可以分为五类:None.数字类型.序列类型.映射类型和集合类型.下面我将分别对他们进行介绍,做个总结以备以后查看.下面的表列出了各个类别下的具体数据类型.*注: ...

  4. Python基础教程:内置类型之生成器

    生成器的定义方式有两种 一种是调用生成器函数 一种是使用生成器表达式语法 调用生成器函数 生成器函数是指在函数体中使用yield表达式仅返回结果的函数.yield表达式仅在定义生成器函数时使用,因此只 ...

  5. python决策树 多分类_Python中的决策树分类:您需要了解的一切

    python决策树 多分类 什么是决策树? (What is Decision Tree?) A decision tree is a decision support tool that uses ...

  6. python 装饰器分类_Python 装饰器(Decorators) 超详细分类实例

    Python装饰器分类 Python 装饰器函数: 是指装饰器本身是函数风格的实现; 函数装饰器: 是指被装饰的目标对象是函数;(目标对象); 装饰器类 : 是指装饰器本身是类风格的实现; 类装饰器 ...

  7. python中文件分类_python实现根据文件格式分类

    本文实例为大家分享了python根据文件格式分类的具体代码,供大家参考,具体内容如下 使用到python内置os模块(对目录或文件的新建/删除/属性查看,还提供了对文件以及目录的路径操作).shuti ...

  8. python生成器yield原理_Python的迭代器和生成器 使用实例及yield的使用

    <派森>(Python)3.13 win32 英文安装版 类型:编程工具大小:21M语言:英文 评分:8.7 标签: 立即下载 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素 ...

  9. python导入图片数据_Python中读取图片的6种方式

    Python进行图片处理,第一步就是读取图片,这里给大家整理了6种图片的读取方式,并将读取的图片装换成numpy.ndarray()格式.首先需要准备一张照片,假如你有女朋友的话,可以用女朋友的,没有 ...

最新文章

  1. cnpm install -g generator-gulp-webapp yo gulp-webapp test-gulp-webapp
  2. 想提高代码水平,做到这点就够了
  3. twitter 监控登陆活动
  4. Debian系列软件管理(第二版)
  5. Sonya and Informatics
  6. boost::log模块实现loging到 syslog 服务器的示例
  7. 用Swashbuckle给ASP.NET Core的项目自动生成Swagger的API帮助文档
  8. 牛客第二场 G.League of Legends-单调队列优化dp
  9. matlab4.0,matlab 4.0
  10. Z-Stack Home Developer's Guide—7.EZ-Mode中文翻译【Z-Stack Home 1.2.0的开发文档】
  11. 利用wxpython编写GUI
  12. 使用 Apache JMeter™工具进行性能测试
  13. java类 权限修饰词_java-学习笔记-访问权限修饰词一
  14. Java帮助文档的生成
  15. Synopsys Mentor Candence
  16. 深度学习框架有什么作用?
  17. 手机html微信登录,添加手机APP微信登录支持,微信公众号单页应用网页授权登录支持...
  18. 变异凯撒(实验吧CTF题库-密码学)
  19. 上传本地仓库到github远程仓库
  20. 数据预处理-Excel 两列合并为一列中间加空格

热门文章

  1. 报告老板:这次的缓存事故是这样的...
  2. 单线程的Redis为什么却能支撑高并发?
  3. 视频人脸检测——Dlib版(六)
  4. C# WinForm窗体四周阴影效果
  5. JDBC中使用PreparedStatement执行SQL语句并管理结果集
  6. C#中其他简单LINQ查询表达式的简单使用介绍
  7. python包和目录有什么不同_python模块和包的区别
  8. sqlserver可视化工具_数据分析之基础分析工具篇(修订版)
  9. yolov4用1050ti_简单粗暴的多目标跟踪神器 – DeepSort
  10. UC浏览器电脑版怎么恢复被关闭的网页