文档章节

黄哥漫谈Python 生成器

黄哥Python培训
 黄哥Python培训
发布于 2016/08/07 07:51
字数 771
阅读 73
收藏 2

黄哥漫谈Python 生成器

何为生成器(Generators) 下面的黄哥用大白话说明。 当Python 函数不用return 返回值,用yield关键字的时候,函数的返回值为生成器对象。

图中代码,函数没有用return 返回值,用yield 输出值,函数的调用返回值为生成器对象, 生成器对象,用p.next()方法返回一个值,函数执行暂停,下次再调用next()方法时,从 暂停处开始执行,print 输出值。再执行第二个yield 返回值。

像上面函数的返回值为生成器对象的函数叫做生成器函数。

生成器是一个可迭代对象,可以用for循环迭代。

特别需要注意的是,初学者容易出现的一个错误是,生成器用next()方法,到最后一个yield 返回值时,再用一次,会报错误StopIteration。

下面图片中p是生成器,用了二次next()方法,相当于返回值都返回完了,再循环迭代没有输出。见过初学者一直问为啥这样,黄哥说“你可以想像成指针”前面已经指到尾部了。所以

for 循环 没有输出。

增强的生成器,有send()和close()方法。

增强的生成器中,除yield可以输出值,也可以从外部send值到生成器内部。这个时候,yield 是表达式,可以输出值,也可以接收值赋值给其他变量。

有近一步学习的,请看

PEP 342 -- Coroutines via Enhanced Generators

https://www.python.org/dev/peps/pep-0342/

下面讲讲生成器实例代码。

1、利用生成器生成可以无限取值的斐波拉切函数。

	#!/usr/bin/env python
	# -*- coding: utf-8 -*-
	# Author: 黄哥python培训 qq:1465376564


	def fib():
	    a, b = 0, 1
	    while True:
	        yield a
	        a, b = b, a + b

	p = fib()
	print [p.next() for i in xrange(101)]

2、求PI值。

	#!/usr/bin/env python
	# -*- coding: utf-8 -*-
	# Author: 黄哥python培训 qq:1465376564
	"""
	1 - 1/3 + 1/5 - 1/7 + ...

	"""


	def pi_series():
	    total = 0
	    i = 1.0
	    j = 1
	    while True:
	        total = total + j / i
	        yield 4 * total
	        i += 2
	        j = j * -1


	def main(g, n):
		for i in range(n):
			yield g.next()

	if __name__ == '__main__':
	    print list(main(pi_series(), 8))

	#[4.0, 2.666666666666667, 3.466666666666667, 2.8952380952380956, 3.3396825396825403, 2.9760461760461765, 3.2837384837384844, 3.017071817071818]

3、生成器处理大日志文本文本。

		# coding:utf-8

		import time
		start_time = time.time()


		def find_ip(path):
		    for line in open(path):
		        s = line.find('"Sogou web spider')
		        if s >= 0:
		            yield line[:s].strip()

		p = find_ip("bigfile.txt")
		p = list(set(list(p)))
		for item in p:
		    print item

		print time.time() - start_time, "seconds"

4、生成器函数也可以玩递归。

		#!/usr/bin/env python
		# -*- coding: utf-8 -*-
		# Author: 黄哥python培训 qq:1465376564


		def spread_list(lst):
		    tmp = []
		    for item in lst:
		        if isinstance(item, list):
		            tmp = spread_list(item)
		            for item2 in tmp:
		                yield item2
		        else:
		            yield item

		l = [1, 2, 3, 4, 5, [6], [7, 8, [9, [10]]]]
		l2 = [[3, 7, [9, 6]], [2, [3, 4], 10], 99, 28]
		l3 = []
		l4 = [3, 4, 5, 8]
		lst = spread_list(l)
		print list(lst)
		lst = spread_list(l2)
		print list(lst)
		lst = spread_list(l3)
		print list(lst)
		lst = spread_list(l4)
		print list(lst)

		# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
		# [3, 7, 9, 6, 2, 3, 4, 10, 99, 28]
		# []
		# [3, 4, 5, 8]

如何训练自己的编程思路

部分免费Python免费视频

感恩!感谢黄哥Python培训学员的支持和肯定

© 著作权归作者所有

共有 人打赏支持
黄哥Python培训
粉丝 39
博文 21
码字总数 14219
作品 0
海淀
私信 提问
运维如何通过学习python学会编程

运维如何通过学习python学会编程 运维必须懂开发,特别是python开发,已经形成大家的共识,不懂开发的运维,路会越走越窄。 黄哥,从2012年底,从事python教学过程中,接触到很多运维的朋友。...

黄哥Python培训
2016/03/01
187
0
黄哥通过代码来说明:python语法糖

下面用一个例子来说明: #coding:utf-8 """ foo = decorator(foo) 语句的作用是将foo函数作为参数传递到decorator 返回值赋值给foo ,那么foo不再是原来的函数了 为了简化代码,python添加了...

黄哥Python培训
2015/11/13
0
0
python生成式生成器详细解答

Python得yield关键字,yield是python中的生成器 了解生成器需要先了解什么是生成式,切片的目的是从已有的列表中切出一部分返回,而生成式的目的则是从无到有的构建一个列表 一个生成式的案例...

开源中国段子手
2015/07/21
0
0
Python3+迭代器与生成器

转载Python3 迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的...

xinet
2017/08/12
0
0
更深入的理解 Python 中的迭代

深入探讨 Python 的 循环来看看它们在底层如何工作,以及为什么它们会按照它们的方式工作。 Python 的 循环不会像其他语言中的 循环那样工作。在这篇文章中,我们将深入探讨 Python 的 循环来...

01%
05/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Elasticsearch通关教程(五):如何通过SQL查询Elasticsearch

  这篇博文本来是想放在全系列的大概第五、六篇的时候再讲的,毕竟查询是在索引创建、索引文档数据生成和一些基本概念介绍完之后才需要的。当前面的一些知识概念全都讲解完之后再讲解查询是...

SEOwhywhy
5分钟前
0
0
以太坊PHP离线交易开发包

EthTool开发包适用于希望采用裸交易的PHP以太坊应用开发,主要包含以下特性: 支持裸交易部署/调用合约 内置etherscan和infura支持 keystore生成与读取,兼容geth/parity 采用裸交易的一个好...

笔阁
32分钟前
1
0
SRE的含义及与 DevOps 如何关联?

虽然站点可靠性工程师(site reliability engineer SRE)角色在近几年变得流行起来,但是很多人 —— 甚至是软件行业里的 —— 还不知道 SRE 是什么或者 SRE 都干些什么。为了搞清楚这些问题...

linuxCool
33分钟前
1
0
月入3万之一个程序员的转行坎坷历程

陈年往事 “我月入3万,怎么会少少了你一个鸡蛋啊?” 这是2017年9月左右的一个新闻,一位煎饼摊大妈因和顾客争执时脱口而出这样一句话而走红。当时还上了各大新闻的头条。 互联网兴起今天,...

苏南-首席填坑官
55分钟前
3
1
OSChina 周一乱弹 —— 眼看着这颗陨石砸了下来

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:分享Nachtblut的单曲《Antik》 《Antik》- Nachtblut 手机党少年们想听歌,请使劲儿戳(这里) @mr_chip :上海的初雪之后有点冷 ...

小小编辑
今天
528
9

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部