概述
什么是生成器(generator)
大家知道,Python中一切皆是对象,生成器也不例外。实际上,生成器也是一种迭代器(iterator),它可以看成是迭代器对象的一种特殊情形。例如,通过以下代码我们可以定义一个可迭代对象“MyRange”。class MyRange:def __init__(self,stop):
self.stop = stop
self.start = 0def __iter__(self):
index = 0while index yield index
index += 1
大家可能发现了吧,以上代码中出现了Python中的一个关键字
“yield”。注意,
Python中的yield关键字通常是生成器对象的标志。我们可以通过以下代码利用可迭代对象“
MyRange””生成一个生成器"generate"。
myrange = MyRange(5)
generate = myrange.__iter__()
print(type(generate))
以上代码运行后,可以打印出“generate”变量的类型为
<class 'generator'>
此时,我们就可以像使用迭代器一样来使用生成器来。比如,我们可以利用for循环去迭代遍历这个生成器。
for i in iterator:
print(i)
同时,我们也可以利用迭代器的另一种访问方法来对生成器进行迭代。
while True:try:
item = generate.__next__()
print(item)except:break
以上两种迭代方法的结果都为:
01234
您可能会问,该生成器的__next__()方法是怎么定义的呢?其实该方法的定义被隐藏了,__next__()方法的函数体实际上就是__iter__()方法的方法体。
2
生成器对象的简化版---生成器函数
前面我们利用可迭代对象“MyRange”生成了一个生成器对象,说明了一个问题,即“生成器对象其实就是一个迭代器对象”。但实际中,我们在利用生成器时,并不会采用以上方法去进行定义。通常我们会通过生成器函数来定义。那么如何利用生成器函数来定义生成器对象呢?我们来看以下代码。
def my_range(n):
i = 0while i yield i
i += 1
请注意,以上代码中出现了一个函数“my_range”。该函数中出现了一个“yield”关键字,实际上,该函数会有一个隐藏的返回值,返回的结果就是一个生成器对象。我们来测试一下。运行以下代码。
print(my_range(5))
结果为
0x0000000002545390>
怎么样,明白了吧。我们容易发现,通过此种方法定义的生成器要远远比前面一种的定义方法简单的多。不是吗?
3生成器对象的遍历的实质
接下来我们来谈一下生成器对象的遍历实质。我们以第二部分中定义的生成器为例。
def my_range(n):
i = 0while i yield i
i += 1
请注意,以上生成器的作用是生成一个从0开始至n-1结束的含有n个整数的生成器对象。接下来,我要遍历该对象。我们说,由于生成器就是一种迭代器,所以,我们就可以采用遍历迭代器的方法来遍历生成器。例如,我们可以用for循环遍历该生成器。
for i in my_range(5):
print(i)
遍历结果为:
01234
接下里,我们来谈一下其遍历过程的实质。其实,生成器的遍历实质与迭代器的遍历实质类似,它是通过关键字“yield”来实现的。以上代码中,其遍历过程如下:
第一次遍历循环,函数my_range会被执行, 当进入函数体后,程序进入while循环,此时i取0,当遇到yield后,程序会将yield后的i值即0返回,因此,第一次遍历结果为0.
第二次遍历循环,函数my_range会再次被触发, 只不过,它不会从头开始运行,它会从上一次循环的位置继续执行,即执行“i+=1”,此时i 更新为1,然后,继续往下执行while循环,直至再一次遇到“yield”,当遇到yield后,程序会将yield后的i值即1返回,因此,第二次遍历结果为1。
然后以此类推去循环遍历,最终得到的就是以上的结果。
怎么样,明白了吗?您可能会问,这样做有什么好处呢?其实很明显,此种遍历循环,可以借助于yield实现循环一次,计算一次,返回一次。这样,若当遍历的数据较大时,我们可以极大的省去内存的开销。
4生成器表达式
我们知道,Python是一门“优雅”的编程语言,其特点就是该类语言中总是会出现一些“骚气”的写法,接下来,介绍一下生成器的“骚气”写法----生成器表达式。
生成器表达式与列表推导式和lamnda表达式类似,都是一种简单优雅的简化版写法。我们来介绍一下。还是以以上定义的生成器对象为例。
def my_range(n):
i = 0while i yield i
i += 1
下面,我将其改为利用生成器表达式来定义,具体写法类似于列表推导式.
my_range = (i for i in range(5))
怎么样,简单否,骚气否?
注意,如果想像访问列表一样访问其元素是行不通的。例如:
print(my_range[0])
此时,程序会报出错误。
TypeError: 'generator' object is not subscriptable
此时我们如果想访问该生成器里面的元素,有两种方法:一种可以利用for循环遍历;另一种,则是使用__next__()方法来进行遍历。以下为利用for循环遍历的实例。
for i in my_range:
print(i)
遍历结果为
01234
-end-
Python 青少年编程
Python教学案例与公益课: 在线教学案例展示(一)-----for循环与while循环的区别Python青少年编程推出公益课堂啦,今天推出第一讲,进来看看吧!Python青少年编程公益课堂第二讲----turtle绘图中的几个重要函数及其应用Python青少年编程公益课堂第三讲----画笔,看我七十二变!Python青少年编程公益课堂第四讲----拔毛变猴,撒豆成兵!Python青少年编程公益课堂第五讲----海龟绘图编程实训(一)Python青少年编程公益课堂第六讲----海龟绘图编程实训(二)Python微课堂系列:
Python微课堂 | 第二讲:变量的类型
Python小课 | 第一讲:变量的那些事
Python微课堂 | 第三讲:Python开发环境的几种安装方式简介
Python微课堂 | 第四讲:Random模块的基本使用方法
Python微课堂 | 第五讲:for循环控制语句的基本使用方法
Python微课堂 | 海龟绘图系列(一):turtle库的基本使用
Python微课堂 | 海龟绘图系列(二):turtle绘图直角坐标系
Python微课堂 | 海龟绘图系列(三):turtle绘图中颜色的使用
Python微课堂 | Python导学部分(一):计算机的组成与工作原理
Python微课堂 | Python导学部分(二): 编程与编程语言
Python微课堂 | Python导学部分(三): Python编程语言简介(第一部分)
Python微课堂 | Python导学部分(四): Python编程语言简介(第二部分)
Python微课堂 | 海龟绘图系列(五):turtle绘图中自定义画笔的使用方法(二)
Python微课堂 | 第六讲:条件嵌套
最后
以上就是高高招牌为你收集整理的python海龟作图不用循环_深入浅出,谈一谈Python中的生成器对象及其设计原理的全部内容,希望文章能够帮你解决python海龟作图不用循环_深入浅出,谈一谈Python中的生成器对象及其设计原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复