首先看一下什么是列表生成式

>>> [i*2 for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> a=[]
>>> for i in range(10):
... a.append(i*2)
...
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

这一句代码就实现了三句代码的效果,这一句代码就是列表生成式

列表如果存的数据太多,就会占用很大的存储空间

如果只取列表中的一些数据,那么其它不用的数据占用的存储空间就白占了

生成器也能存储数据,但是它只记录当前数据,剩下的数据都还没生成,这样就不会占用太多的存储空间

怎么创建一个生成器呢?

>>> [i*2 for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> (i*2 for i in range(10))
<generator object <genexpr> at 0x0000021C9C2E5258>

这样就是一个生成器了,没有直接生成数据

要取一个数据就生成一个数据

那么怎么获取生成器里的数据呢?

>>> b = (i*2 for i in range(10))
>>> b
<generator object <genexpr> at 0x0000021C9C2E5308>
>>> b.__next__()
0
>>> b.__next__()
2
>>> b.__next__()
4
>>> next(b)
6
>>> next(b)
8
>>> next(b)
10

生成器使用next()方法获取数据,next(b),这是Python3和Python2通用的方法

Python3中还可以用__next__()方法,b.__next__()

Python2中用next()方法,b.next()

但是用next()方法一次次取数据太麻烦,所以通常都用for循环来打印数据

>>> c = (i*2 for i in range(10))
>>> for n in c:
... print(n)
...
0
2
4
6
8
10
12
14
16
18

如果函数里有yield关键字,这个函数就是生成器

# -*- coding:utf-8 -*-
__author__ = "MuT6 Sch01aR" def test(n):
m = 0
b = 0
while m<n:
print("before yield")
yield b
b = b+3
print("after yield")
m =m+1
return "test return" a =test(10) while True:
try:
b = a.__next__()
print("in the next",b)
except StopIteration as e:
print(e.value) #StopIteration的value为生成器的返回值
exit()

运行结果

运行过程:

首先是调用test()函数

然后执行while循环

到__next__()方法的时候,跳到test()函数

执行完yield后,没继续执行下面的语句,而是返回到__next__()方法后的语句

执行完该语句后继续执行while循环,执行__next__()方法

然后又跳转到yield后的语句

生成器调用next()方法的时候执行,执行到生成器中的yield的时候返回,然后执行next()方法后的语句,再执行到next()方法的时候,就会跳到执行yield的语句,之后执行yield后的语句

用生成器实现单线程多并发

# -*- coding:utf-8 -*-
__author__ = "MuT6 Sch01aR" import time def consumer(name):
print('%s准备吃包子' %name)
while True:
baozi = yield
print('%s包子来了,被%s吃了' %(baozi,name)) def producer():
c = consumer('张三')
c2 = consumer('李四')
c.__next__()
c2.__next__()
print('我开始准备做包子了')
for i in range(10):
time.sleep(1)
print('我做了2个包子')
c.send('肉') #调用yield,并传值
c2.send('菜') if __name__ == '__main__':
producer()

send方法不仅可以调用yield,还给yield传值

运行结果

实现了单线程多并发的效果

Python函数(十一)-生成器的更多相关文章

  1. python函数-迭代器&生成器

    python函数-迭代器&生成器 一.迭代器 1 可迭代协议 迭代:就是类似for循环,将某个数据集内的数据可以“一个挨着一个取出来” 可迭代协议: ① 协议内容:内部实现__iter__方法 ...

  2. Python函数04/生成器/推导式/内置函数

    Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...

  3. Python函数-5 生成器

    生成器有时候,序列或集合内的元素的个数非常巨大,如果全制造出来并放入内存,对计算机的压力是非常大的.比如,假设需要获取一个10**20次方如此巨大的数据序列,把每一个数都生成出来,并放在一个内存的列表 ...

  4. python——函数之生成器

    1 生成器函数的含义    生成器是一个返回可以迭代对象的函数,它是一个特殊的迭代器,但迭代器的抽象层级更高且比较复杂需要实现很多方法.相较迭代器而言,生成器简单使用. 2 生成器的创建方式 2.1 ...

  5. Python第十一天 异常处理 glob模块和shlex模块 打开外部程序和subprocess模块 subprocess类 Pipe管道 operator模块 sorted函数 os模块 hashlib模块 platform模块 csv模块

    Python第十一天    异常处理  glob模块和shlex模块    打开外部程序和subprocess模块  subprocess类  Pipe管道  operator模块   sorted函 ...

  6. python 函数之装饰器,迭代器,生成器

    装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...

  7. Python —— 函数高级特性(切片、迭代、列表生成式、生成器、迭代器)

    一.切片(Slice) 在很多编程语言中,针对字符串提供了很多截取函数(i.e.  substring),目的就是对字符串切片.python中没有针对字符串的截取函数,需要通过“切片”来完成. 取一个 ...

  8. Python函数——列表推导式、生成器与迭代器

    列表推导式 产生背景 现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,你怎么实现? 第一种方法: a = [1,3,4,6,7,7,8,9 ...

  9. python中的生成器函数是如何工作的?

    以下内容基于python3.4 1. python中的普通函数是怎么运行的? 当一个python函数在执行时,它会在相应的python栈帧上运行,栈帧表示程序运行时函数调用栈中的某一帧.想要获得某个函 ...

随机推荐

  1. 016-Spring Boot JDBC

    一.数据源装配 通过查看代码可知,默认已装配了数据源和JdbcTemplate System.out.println(context.getBean(DataSource.class)); Syste ...

  2. 在C语言中使用syslog打印日志到日志文件

    参见 <unix 环境高级编程>第13 章 精灵进程 Syslog为每个事件赋予几个不同的优先级: LOG_EMERG——紧急情况 LOG_ALERT——应该被立即改正的问题,如系统数据库 ...

  3. 第12条:不要在for和while循环后面写else块

    核心知识点: (1)一般的if/else是前面不执行,后面才执行,循环下面的else是前面执行完后面才会执行,如果是break打断也不会执行.循环为空或False也不执行. (2)try/expect ...

  4. ThinkPHP 3.2.2 事务

    手册里说得非常清楚 : 5.3.19 事务支持 ThinkPHP提供了单数据库的事务支持,如果要在应用逻辑中使用事务,可以参考下面的方法: 启动事务: PHP代码 $User->startTra ...

  5. java WEB学习笔记32:HttpSession 接口常用方法 及 HttpServletRequest接口中的Session方法 Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. Delphi 中关闭指定进程的方法

    Uses Windows, SysUtils, Tlhelp32 ; Function KillTask( ExeFileName: String ): Integer ; //关闭进程 Functi ...

  7. Oracle的基本操作

    一.ORACLE的启动和关闭 1.在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a.启动ORACLE系统 oracle>svrmgrl ...

  8. UOJ71 【WC2015】k小割

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  9. LUA学习之一 初次接触

    对于一个开源工程,开始学习它的第一步自然是编译工程. 使用vc编译lua,在网上已有许多介绍,但“纸上得来终觉浅”,自己走一遍还是有必要的. 步骤如下: 1.下载源代码,从lua.org下载最新源代码 ...

  10. spring boot: scope (一般注入说明(一) @Autowired注解)

    实例一: DiConfig 文件: package di; import org.springframework.context.annotation.ComponentScan; import or ...