生成器

 生成器的特点

一、内存空间的角度
1、普通列表会将所有元素存到内存中,因此可以进行切片式操作。如果列表元素很多,加载到内存中的时间就会很长。
2、生成器只能for循环的过程中提取,根据垃圾清理机制,无论生成器内有多少元素,都只会占用一个内存地址。
 
 
二、调用方式:
1、普通列表的调用方法有很多,比如切片,添加,删除等等。
2、生成器只有在调用时才会生成相应的数据,调用方式有 " str__next__.()   str.send() ",并且每调用一次就产生一个值调用到最后一个值后会报错(可用:异常处理)。
 
注意:
next:是直接调用yield,并不会传值。
send:是调用并直接传值给yield。
 
 
 
三、列表生成器和生成器格式:
1、列表生成器:
[ i * 2 for i in range(10) ]
结果显示:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
 
 
2、生成器:
( i * 2 for i in range(10) )
结果显示:<generator object <genexpr> at 0x00000000006E87D8>
 
注意:如果有1亿行记录
第一个格式的效果可能花费5分钟或者跟多时间。
第二个格式基本上是毫秒级的,因为只获取一个内存地址

 
 

列表生成器

一、列表生成器的种类:
1、普通列表:
a = [1,2,3]
 
2、列表生成器:(每次循环都*2)
[i*2 for i in range(10)]
 
1 相当于:
2 a = []
3 for i in rang(10):
4     a.append(i*2)
5  
6 print(a)

注意:类似python 2.7里的range(100)和xrange(100)
1、rang:是逐个返回1~100范围值。
2、xrang:是返回一个内存地址,该地址包含了100的值,只有在for循环时才会显示
3、使用xrang的优势,结合python的垃圾回收机制,可以循环使用同一个

 
 
二、两个列表的区别:
a:是写死的。
列表生成器:是可扩展的。
 
 

生成器概念

1、具有生成能力的函数叫生成器。
2、具有取东西能力的函数叫迭代器。
3、主要关注生成器如何去写;迭代器主要是python内部封装好的;无需过多关注
 
 
 
一、通过filter进行结果过滤:
 1 li = [11,22,33,44,55,34]
 2 result= filter(lambda x:x>33,li)
 3 print(result)
 4 
 5 返回一个对象:
 6 <filter object at 0x0000000000A55128>
 7 
 8 
 9 #返回结果:具有生成指定条件数据的能力的一个对象。只有在循环它的时候生成
10 #是一个内存地址,该地址包括大于33的所有值
11 #该结果只有在for循环时才会显示
View Code

 

二、使用yield()转成生成器。
 1 def func():
 2    yield 1
 3    yield 1
 4    yield 1
 5 
 6 ret  = func()
 7 print('ret:',ret)
 8 
 9 显示结果
10 ret: <generator object func at 0x0000000000A38938>
11 
12 
13 #只要函数中出现yield,则会变成生成器,返回内存地址<generator object func at 0x00000000011388E0>
View Code

 

当用for循环遍币ret时,内存地址则会转换成数值,如下:
1 for i in ret:
2     print('foi循环:',i)
3 
4 
5 
6 显示结果:
7 foi循环: 1
8 foi循环: 1
9 foi循环: 1
View Code
注释:
当for循环进入函数时,会找到yield1,并打印1,然后返回结果。
当在一次for循环时,会找到上一次的执行结果1,然后从上次执行结果后在执行一个2,并且返回。
多次for循环,以此类推。
 
 
 
三、生成器的属性:
生成器是由于函数创建的,而函数名就是生成器。
 1 def myrange(arg):
 2     start = 0
 3     while True:
 4         if start > arg:
 5             return
 6         yield  start
 7         start += 1
 8 
 9 ret = myrange(3)
10 
11 r = ret.__next__()  #进入函数,找到yield,获取yield后面的数据,每运行一次,生成器就会往下执行一个数值:
12 print(r)
13 r = ret.__next__()
14 print(r)
15 r = ret.__next__()
16 print(r)
17 r = ret.__next__()
18 print(r)
19       
20        显示结果:
21 0
22 1
23 2
24 3
创建一个myrang的生成器:

 

 
 
 
 
 
 
 
 
 
 
 
posted @ 2017-12-25 16:46  风之岚翔  阅读(89)  评论(0编辑  收藏