Python 生成器
来源:互联网 发布:网络金融诈骗 编辑:程序博客网 时间:2024/05/20 20:21
生成器(generators):
当需要一个庞大的列表数据时,用列表解析创建这样一个列表(列表解析,总是先生成列表,然后再执行其他内容,虽然这样消耗内存,降低性能),然后再当需要的时候,遍历列表获取列表中的元素,当数据量很大是, 就占用内存,降低性能;
为了完善列表解析的性能上的弊端,引入了“生成器” 的概念:
生成器:
当需要某一庞大的列表数据时,用生成器来代替列表解析,生成器并不首先生成所需的列表,而是在需要的时候才会计算出数据,来共调用者使用,因此,生成器没被调用时仅仅是占用很小内存的一个算法,并不包含数据,仅在生成器被调用时执行算法,并返回一个需要的数据。
列表解析表达式与生成器表达式: 区别仅仅是 [ ] 与 ( ) 的不同。
>>> list1 = [x for x in range(12)] # 列表解析表达式>>> type(list1)<class 'list'>>>> generators1 = (x for x in range(12)) # 生成器表达式, x for x in range(12) 就是一个算法,只在调用时运行>>> type(generators1)<class 'generator'>list1 可以用list的方法调用,但是generators1是生成器对象,只能用 next()方法调用:
>>> list1[2]2>>> list1[1]1>>> for i in list1:print(i, end=' ')0 1 2 3 4 5 6 7 8 9 10 11 >>> generators1<generator object <genexpr> at 0x0000000002BE0BA0> # 生成器对象不含数据,仅仅是一个对象
>>> next(generators1)0>>> next(generators1)1>>> next(generators1)2>>> next(generators1生成器除了 减少占用内存,提高性能外,最大的特点就是:中断、挂起并继续执行。
中断、挂起,并保存上次运行状态,再重新开始。直到生成器(generators)产出所有的值,再次调用报错: StopIteration . 停止迭代。
>>> next(generators1)0>>> next(generators1)1>>> next(generators1)2>>> next(generators1)3>>> next(generators1)4>>> next(generators1)5>>> next(generators1)6>>> print(list1)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]>>> next(generators1)7>>> next(generators1)8>>> next(generators1)9>>> next(generators1)10>>> next(generators1)11>>> next(generators1)Traceback (most recent call last): File "<pyshell#27>", line 1, in <module> next(generators1)StopIteration>>>
生成器的用法不仅仅局限于上面的例子:更广泛的应该是 生成器函数。
生成器函数:
与其他函数的不同仅仅是增加了 一个关键字 yield (产生)。
return 在函数中的作用是: 返回值,并结束函数的运行。
yield 在生成器函数中作用是: 产生一个值,并挂起函数的运行状态 ,等待再次运行。
yield 就是专门给生成器用的 return
生成器的send() 方法:
即然生成器可以 挂起 并保存运行状态(包括参数),那么就应该可以改变参数后,继续运行。send() 就起到这样的作用(传参)。
参考代码例子:
import randomdef get_data(): """返回0到9之间的3个随机数""" return random.sample(range(10), 3)def consume(): """显示每次传入的整数列表的动态平均值""" running_sum = 0 data_items_seen = 0 while True: data = yield # 挂起,等待传参,并赋值给data data_items_seen += len(data) running_sum += sum(data) print('The running average is {}'.format(running_sum / float(data_items_seen)))def produce(consumer): """产生序列集合,传递给消费函数(consumer)""" while True: data = get_data() print('Produced {}'.format(data)) consumer.send(data) yield # 暂停挂起,等待再次被调用if __name__ == '__main__': consumer = consume() consumer.send(None) producer = produce(consumer) for _ in range(10): # 循环10次 print('Producing...') next(producer) # 调用生成器函数输出:
Producing...Produced [4, 0, 1]The running average is 1.6666666666666667Producing...Produced [5, 7, 8]The running average is 4.166666666666667Producing...Produced [2, 3, 1]The running average is 3.4444444444444446Producing...Produced [5, 7, 2]The running average is 3.75Producing...Produced [4, 0, 5]The running average is 3.6Producing...Produced [6, 4, 7]The running average is 3.9444444444444446Producing...Produced [7, 5, 2]The running average is 4.0476190476190474Producing...Produced [7, 0, 5]The running average is 4.041666666666667Producing...Produced [4, 1, 6]The running average is 4.0Producing...Produced [7, 8, 3]The running average is 4.2
这里先贴上参考文章链接:http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained?lang=chs&page=1#
- Python 生成器
- Python生成器
- python生成器
- python 生成器
- python生成器
- python生成器
- python生成器
- python生成器
- python 生成器
- python生成器
- python 生成器
- python生成器
- python 生成器
- Python--生成器
- python 生成器
- Python 生成器
- python-生成器
- Python生成器
- 图像处理之移动模糊
- 配置文件中 The word is not correctly spelled
- Android常用adb命令总结
- MySQL--数值运算符和函数、比较运算符和函数
- 新手小白的Java之路
- Python 生成器
- 货币
- 埃及分数式 使用枚举法求解分数3/11的所有3项埃及分数式
- 打包发布自己的nodejs包
- flask ---blog 出现的问题总结
- Kafka 低级API 查看topic
- resizeTo()- 会移动的窗口
- windows 10 下sublime text 3配置c/c++编译环境
- android 教你如何导入、使用类库