python海龟作图不用循环_深入浅出,谈一谈Python中的生成器对象及其设计原理

91e9e3174eb2253e625f80f8137b7ecb.png朋友们好,前几天发了一篇文章,特地谈了一下Python中的可迭代对象与迭代器对象(深入浅出,谈一谈Python中的可迭代对象及其迭代原理)。本讲,我想再来深入的谈一下Python中的生成器对象。 1

什么是生成器(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))

怎么样,简单否,骚气否?

771eb848f069e25597c89deb4ef172f1.png

注意,如果想像访问列表一样访问其元素是行不通的。例如:

print(my_range[0])

此时,程序会报出错误。

TypeError: 'generator' object is not subscriptable

此时我们如果想访问该生成器里面的元素,有两种方法:一种可以利用for循环遍历;另一种,则是使用__next__()方法来进行遍历。以下为利用for循环遍历的实例。

for i in my_range:
    print(i)

遍历结果为

01234
-end-

09df9a71860e755a1f38253b5fdb6466.png

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微课堂  |  第六讲:条件嵌套

f2b20b65f256993c98e5b18422c23c47.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值