列表生成式

需求:列表[0,1,2,3,4,5,6,7,8,9]每个值加1,如何实现?

方法1:列表追加

 >>> a = [0,1,2,3,4,5,6,7,8,9]
>>> b = []
>>> for i in range(10):
... b.append(i+1)
...
>>> b
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a = b
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

方法2:原值修改enumerate

 >>> a = [0,1,2,3,4,5,6,7,8,9]
>>> for index,i in enumerate(a):
... a[index] += 1
...
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

方法3:map函数

 >>> a = [0,1,2,3,4,5,6,7,8,9]
>>> a = map(lambda x:x+1,a)
>>> a
<map object at 0x000000000299FF60>
>>> for i in a: print(i)
...
1
2
3
4
5
6
7
8
9
10

方法4:列表生成,作用:使代码更简洁

 >>> a = [i+1 for i in range(10)]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成器

当list列表很大,比如100万条,只使用几个,而不是使用那么多,如果全部放进内容占用空间很大,使用一种机制:边循环边计算,称为生成器

元组:

 >>> b = (i*2 for i in range(10))
>>> b
<generator object <genexpr> at 0x00000000029981A8>
>>> for i in b:
... print(i)
...
0
2
4
6
8
10
12
14
16
18

列表:

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

两者区别:最外层的[]和(),一个是list,一个是generator生成器。

如何打印其中的元素:

列表list:

 >>> c[9]
18
>>> len(c)
10

元组generator:生成器使用元组,只有被调用了才会生成数据,调用哪生成哪。调用方法:next()

 >>> b[9] #生成器没有像列表一样的下标操作
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'generator' object is not subscriptable
 >>> b = (i*2 for i in range(10))
>>> next(b)
0
>>> next(b)
2
>>> next(b)
4
>>> next(b)
6
>>> next(b)
8
>>> next(b)
10
>>> next(b)
12
>>> next(b)
14
>>> next(b)
16
>>> next(b)
18
>>> next(b) #next只记录当前位置,调用到最后一个再调用就会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

next()方法调用到最后一个后再调用就会抛出StopIteration错误异常,正确的方法:

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

举例1:斐波那契数列1,1,2,3,5,8,13...,函数代码为

 def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done' fib(10)
1
1
2
3
...
55

赋值语句:a,b = b,a+b  相当于 t=(b,a+b) a=t[0] b=t[1]

生成器写法:

 def fib(max):
n, a, b = 0, 0, 1
while n < max:
#print(b)
yield(b) #有yield关键字就不是普通函数,而是一个生成器generator
a, b = b, a + b
n = n + 1
return '异常了' #11个next方法执行后,就会抛出异常Stop Iteration:异常了,所以return返回的是异常消息 f=fib(10) #生成器必须被调用才能生效
#print(f.__next__()) #使用next方法调用
for i in f: #正确调用方式如下
print(i)

总结:有yield函数就是一个生成器,return返回异常消息。yield保存函数中断状态,想什么时候回来就什么时候回来。

生成器的作用:函数是顺序执行,遇到return或最后一行语句就结束执行;生成器在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。(断点执行下看看)

yield实现单线程情况下并发!!!

 举例2:典型的生产者消费者模型

 import time
def consumer(name):
print("%s准备吃包子了"%name)
while True:
baozi = yield #没有yield返回值,表示为空
print("包子[%s]来了,被[%s]吃了"%(baozi,name))
c = consumer("A")
c.__next__()
执行结果:
A准备吃包子了 再添加一行代码:
c.__next__()
包子[None]来了,被[A]吃了 分析:
第一次程序执行顺序:
def consumer---c=consumer("A")使得c变成generator生成器---c.__next__()调用生成器--def consumer(name = "A")--print---while True---baozi=yield--返回为空退出,底下的print(包子被谁吃了)不执行 第二次程序执行顺序:
def consumer---c=consumer("A")使得c变成generator生成器---c.__next__()调用生成器--def consumer(name = "A")--print---while True---baozi=yield--第二个c.__next__()---baozi=yield---print(包子被谁吃了)---baozi=yield---返回为空退出

注:生成器只有g.__next()__方法调用,同t = next(g)一样。

执行结果:

A准备吃包子了
包子[None]来了,被[A]吃了

 import time
def consumer(name):
print("%s准备吃包子了"%name)
while True:
baozi = yield #没有yield返回值,表示为空
print("包子[%s]来了,被[%s]吃了"%(baozi,name))
c = consumer("A")
c.__next__() b1 = "韭菜馅"
c.send(b1)
c.__next__() 执行结果:
A准备吃包子了
包子[韭菜馅]来了,被[A]吃了
包子[None]来了,被[A]吃了 next和send区别?
next只是调用yield,send不仅调用还给yield传值

最终代码:单线程下的并行效果叫协程。

 import time
def consumer(name):
print("%s准备吃包子了"%name)
while True:
baozi = yield #没有yield返回值,表示为空
print("包子[%s]来了,被[%s]吃了"%(baozi,name))
# c = consumer("A")
# c.__next__()
#
# b1 = "韭菜馅"
# c.send(b1) def producer(name):
c = consumer('A') #两个消费者
c2 = consumer('B')
c.__next__() #调用,打印“准备吃包子”
c2.__next__()
print("开始准备做包子了")
for i in range(10):
time.sleep(1) #每1s钟做2个包子
print("做了2个包子")
c.send(i)
c2.send(i) producer("alex") 执行结果:
A准备吃包子了
B准备吃包子了
开始准备做包子了 做了2个包子
包子[0]来了,被[A]吃了
包子[0]来了,被[B]吃了
....
做了2个包子
包子[9]来了,被[A]吃了
包子[9]来了,被[B]吃了 分析:三行三行的打印,好像是并行的,类似nginx异步IO的效果

Day4-生成器generator的更多相关文章

  1. Python复习之生成器 generator

    生成器 generator def h(): print "hello" m = yield 5 print "m:", m d = yield 12 prin ...

  2. 生成器(generator)内部解析

    #http://kb.cnblogs.com/page/87128/(未看完)

  3. 生成器generator

    生成器generator 定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器 代码: def cash_out(a ...

  4. ES6中的迭代器(Iterator)和生成器(Generator)

    前面的话 用循环语句迭代数据时,必须要初始化一个变量来记录每一次迭代在数据集合中的位置,而在许多编程语言中,已经开始通过程序化的方式用迭代器对象返回迭代过程中集合的每一个元素 迭代器的使用可以极大地简 ...

  5. Hibernate中的主键生成器generator

    本文讲述Hibernate的generator属性的意义.Generator属性有7种class,本文简略描述了这7种class的意义和用法. [xhtml] view plaincopy <c ...

  6. Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)

    迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...

  7. 廖雪峰老师博客学习《通过生成器generator生成列表式杨辉三角》

    说明:这是我接触生成器概念后,自己对它的理解,可能比较表面,没深入理解,也可能有错误.后续校正错误认知,将有关generator作为一个tag了! 希望以后能活用. 先贴出自己写的triangles( ...

  8. 003_生成器(generator)内部解析

    #http://kb.cnblogs.com/page/87128/(未看完)

  9. Python之生成器(generator)和迭代器(Iterator)

    generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用y ...

  10. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

随机推荐

  1. C++实现动态顺序表

    顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构.这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的.只要知道了第一个元素的存 ...

  2. dotnet Core 调用HTTP接口,系统大量CLOSE_WAIT连接问题的分析,尚未解决。

    环境: dotnet core 1.0.1 CentOS 7.2 今天在服务器巡检的时候,发现一个服务大量抛出异常 异常信息为: LockStatusPushError&&Messag ...

  3. 微信小程序,前端大梦想(一)

    小程序框架MINA简介       微信公众平台"小程序"具有不是APP胜似APP的效果,是一种不需要下载安装即可使用的应用,它实现了应用"触手可及"的梦想,用 ...

  4. C++ fstream 详解

    最近在写哈夫曼压缩,遇到了一个比较让人头疼的问题,那就是对文件的读写操作,尤其是以二进制的形式来读写,无奈C++Primer第五版上写的并不详细,很多让人困惑的地方没有涉及或者没有讲清楚.于是这几天我 ...

  5. 开源的C#实现WebSocket协议客户端和服务器websocket-sharp组件解析

    很久没有写博客了(至少自己感觉很长时间没有写了),没办法啊,楼主也是需要生活的人啊,这段一直都在找工作什么的.(整天催我代码的人,还望多多谅解啊,我会坚持写我们的项目的,还是需要相信我的,毕竟这是一个 ...

  6. CI框架浅析(二)

    该文延续上篇文章: CI框架浅析(一) 在CI框架的核心库中,CodeIgniter.php负责加载所有需要的类库,第一个加载的是公共库 core/Common.php Common.php 负责加载 ...

  7. Python多层目录模块调用

    一. 引用模块在 父+级目录中: 1. 将导入模块所在目录(../model/模块)添加到系统环境变量path下,可添加多个 import syssys.path.append("../mo ...

  8. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  9. angular 自定义filter

    用modul.filter .filter("fiilterCity",function(){ return function(obj){ var newObj = []; ang ...

  10. yeoman 使用问题总结

    1.今天尝试使用yeoman,执行grunt server 时报错: cannot find where you keep your bower packges 需要将bower npm instal ...