(一)生成器(Generator)

Python生成器是创建迭代器的简单方法。简单来说,生成器是一个函数,它返回一个我们可以迭代的对象(迭代器)(一次一个值)。

因为下面会用到列表生成式,这里先说明下列表生成式:

列表生成式:

theLi = [i*i for i in range(10)]

下面这段代码的效果和上面的列表生成式是一样的(一开始可能不太习惯列表生成式的写法,多写几次就习惯了):

L = []
for i in range(10):
L.append(i*i)

可在IDE中将结果打印出来.

(二)创建生成器

1、将列表生成式的[]换成()就行了。

 theLi = [i*i for i in range(10)]

 print(theLi)
#创建一个生成器
theGe = (i*i for i in range(10)) print('生成器:',theGe)

可以看到,print('生成器:',theGe)输出的是一个生成器对象,不会直接输出结果

2、在函数中定义yield语句就行了(执行到yield语句时,就会返回结果,不过生成器函数和普通函数还是有区别的,下面会说明)

def theGe():
i = 1
yield i print(type(theGe()))

(三)生成器函数和普通函数的区别

1、Generator函数包含一个或多个yield语句。

2、调用生成器函数时,它返回一个生成器对象,但不会立即执行。

3、生成器函数会自动实现__iter__()__next__()方法。

4、执行顺序不同:普通函数执行到最后一句或者return语句时,就返回结果.而生成器函数,则是每次调用next()方法时执行,遇到yied语句就返回结果,再次执行时从上次结束的yield语句处开始执行.(执行顺序的问题,设个断点运行一次就清楚了)。

5、局部变量和状态会被保存,一直到下一次调用。

6、函数结束时,抛出StopIteration异常。

举个例子:

 from collections import Iterable
from collections import Iterator def gen(): i = 1
print('第一次:',end='')
yield i
i += 1
print('第二次:',end='')
yield i
i += 1
print('第三次:',end='')
yield i print(type(gen()))
#生成器也是迭代器
print(isinstance(gen(),Iterable))
print(isinstance(gen(),Iterator)) g = gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g))

(四)生成器的使用

例如:使用生成器实现杨辉三角

比较简单的一种理解方式,将每一行都看成一个列表,通过末尾补0的方式来计算下一行列表的值.

例如:我们知道第二行的元素,我们可以通过下面这种方式获得三行的元素(这个规律是通用的)

 #第二行
L2 = [1,1] L2.append(0) #此时变成了[1,1,0] L3 = []
# 列表的索引为-1的时候,值=0. L2[-1] = 0
L3.append(L2[-1] + L2[0])
L3.append(L2[0]+L2[1])
L3.append(L2[1]+L2[2]) print(L3)

而下面这段代码

 L3  = []
# 列表的索引为-1的时候,值=0. L2[-1] = 0
L3.append(L2[-1] + L2[0])
L3.append(L2[0]+L2[1])
L3.append(L2[1]+L2[2])

其实就是:

L3  = []
for i in range(len(L2)):
L3.append(L2[i-1] + L2[i])

也是(列表生成式的写法):

 L3  = [L2[i-1]+L2[i] for i in range(len(L2))]

实现杨辉三角:

 #杨辉三角
def yhTriangles(n):
yh = [1]
while len(yh) <= n:
yield yh
yh.append(0)
yh = [yh[i-1] + yh[i] for i in range(len(yh))] for i in yhTriangles(10):
print(i)

(五)使用生成器的优势

1、易于实现,代码更简洁,容易阅读。(例如:使用迭代器我们需要自己去定义__iter__()和_next_()方法,而生成器会自动处理这些

2、对内存更加友好.例如:我们创建一个列表的时候,是一创建就存放到内存中的,如果数据量很大,毫无疑问会占用大量内存(而很多时候,我们可能并不需要访问所有数据)。如果列表元素可以通过某种算法推算出来,一边循环一边计算,这样就能节省大量的内存。Python的生成器就可以实现这种功能.

3、生成器可以代表一个无限的数据流.(无限的数据流是不能直接存放到内存中的,因为内存是有限的)

Python笔记(十七):生成器的更多相关文章

  1. python笔记2 生成器 文件读写

    生成器 一边循环一边计算的机制,称为生成器(Generator). 把一个列表生成式的[]改成(),就创建了一个generator: 创建了一个generator后,通过for循环来迭代它. 著名的斐 ...

  2. Python笔记(十七)_面向对象编程

    面向对象编程 概念:简称OOP,是一种程序设计思想:OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数 面向对象的设计思想:抽象出类class,根据类class创建实例对象instan ...

  3. Python学习笔记014——生成器Generator

    1 生成器定义 在Python中,一边循环一边计算的机制,称之为生成器(generator). 生成器是一个迭代器. 含有yield语句的函数是生成器函数,该函数被调用时返回一个生成器对象(yield ...

  4. python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容

    python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖 ...

  5. python笔记 - day5

    python笔记 - day5 参考: http://www.cnblogs.com/wupeiqi/articles/5484747.html http://www.cnblogs.com/alex ...

  6. python笔记之itertools模块

    python笔记之itertools模块 itertools模块包含创建有效迭代器的函数,可以用各种方式对数据进行循环操作,此模块中的所有函数返回的迭代器都可以与for循环语句以及其他包含迭代器(如生 ...

  7. s21day22 python笔记

    s21day22 python笔记 一.内容回顾及补充 模块补充 importlib.import_module:通过字符串的形式导入模块 #示例一: import importlib # 用字符串的 ...

  8. guxh的python笔记一:数据类型

    1,基本概念 1.1,数据类型 基本数据类型:字符串,数字,布尔等 引用数据类型:相对不可变(元组),可变(列表,字典,集合等) 基本数据类型存放实际值,引用数据类型存放对象的地址(即引用) ==:判 ...

  9. Python:笔记(7)——yield关键字

    Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...

  10. Python:笔记(4)——高级特性

    Python:笔记(4)——高级特性 切片 取一个list或tuple的部分元素是非常常见的操作.Python提供了切片操作符,来完成部分元素的选取 除了上例简单的下标范围取元素外,Python还支持 ...

随机推荐

  1. .Net 环境下比较各种数据库插入操作的性能

    1.简介 再说Windows的异步I/O操作前,先聊聊一些题外话,能帮助我们更好的理解异步I/O操作,常规的Web程序,当用户发起一次请求,当请求通过管道到达客户端的这个过程,会唤起一个线程池线程(后 ...

  2. 浅谈《think in java》:一 对象导论总结

    清单1. 抽象机制,面向对象程序设计方式 java所基于Smalltalk的特性表现一种纯粹的面向对象设计方式: 万物都是对象 程序是对象的集合(容器),他们通过发送消息(发送请求)来告知彼此所要做的 ...

  3. TCP/IP 笔记 - TCP保活机制

    TCP协议中不存在轮询机制,这意味着加入启动一个客户端进程,与服务器建立连接后,然后离开几小时.几天.甚至几个月,连接依然会保持着.理论上,中间路由器可以崩溃和重启,数据线可以断开再连接,只要连接两端 ...

  4. 《用OpenResty搭建高性能服务端》笔记

    概要 <用OpenResty搭建高性能服务端>是OpenResty系列课程中的入门课程,主讲人:温铭老师.课程分为10个章节,侧重于OpenResty的基本概念和主要特点的介绍,包括它的指 ...

  5. ELK实践(二):收集Nginx日志

    Nginx访问日志 这里补充下Nginx访问日志使用的说明.一般在nginx.conf主配置文件里需要定义一种格式: log_format main '$remote_addr - $remote_u ...

  6. Apache-Flink深度解析-SQL概览

    你可能感兴趣的文章: Flink入门 Flink DataSet&DataSteam API Flink集群部署 Flink重启策略 Flink分布式缓存 Flink重启策略 Flink中的T ...

  7. MySQL表行数查询最佳实践

    日常应用运维工作中,Dev或者db本身都需要统计表的行数,以此作为应用或者维护的一个信息参考.也许很多人会忽略select count(*) from table_name类似的sql对数据库性能的影 ...

  8. Oracle SQL 开发误区探索

    本文内容摘自<剑破冰山--Oracle开发艺术>一书. 1.避免对列运算 要善于通过等价改写消除 SQL 中对列的运算,这样可以避免索引无法使用. 2.消除隐式转换 3.关注空格(避免粗心 ...

  9. solr(五): centos中, 整合 tomcat&solr

    前言 虽然windows下, tomcat和solr整合起来灰常的方便, 但是, 一般像这种东西, 都很少部署在windows中, 更多的是部署到linux中去. 其实, 步骤是一样的, 这里, 我在 ...

  10. 开始翻译Disruptor

    刚开始接触Disruptor,看了作者的博客,发现这个大牛很与众不同,他不仅讲解自己的框架的设计思想,还深度介绍了这样设计的原因,其知识范围涵盖了操作系统.数据结构.计算机组成,很有学习的价值.网上有 ...