Python基础滚固故弄玄虚的迭代器与生成器

Posted 圆圆她爹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础滚固故弄玄虚的迭代器与生成器相关的知识,希望对你有一定的参考价值。

我一个初学编程者,第一次看到迭代器,生成器这些名词的时候真的是一脸懵逼,这TMD的到底是个什么鬼?反复研究,查阅资料后,终于把这两个二货给搞明白了。

或许计算机学者们平时一直对着电脑,不太与周围人交流,总爱使用那么拗口的名词,让人无法理解,难道就不能用点通俗点的词汇吗?毕竟计算机科学是一门应用科学啊,脱离了生活,计算机啥都不是。

先来看以下图片

你可能会说,让我看一大堆钱干什么!明明知道我缺钱!

别急!把一张纸钞想象成一个数据,上图是不是就是一大堆散乱的数据呢?

再看下图

装这些 钱(数据)的麻袋,箩筐,就叫 容器,容器就像麻袋,箩筐一样,分好多种,有list,set,dict,tuple,str 等等。

有些收藏家,就爱把纪念钞单独放在一个相框里,相框也是容器,但是与麻袋不一样的是相框取出来的就那么一张纪念币,麻袋可以连续取出很多钞票来一张张看一张张数(遍历),

这种能够连续重复一张张看的遍历动作就叫迭代,所以麻袋是一个很好的可迭代对象,而装有一张纪念币的相框就不是可迭代对象。

1 bag = ["$", "¥", "£", ""] #一麻袋装了美金,毛爷爷,英镑,欧元

装钱(数据)的麻袋(容器)有了,总要有人去数钱(遍历迭代)吧,得请个工人去数钱,这个工人就是Python内置函数iter()

1 bag = ["$", "¥", "£", ""] #一麻袋装了美金,毛爷爷,英镑,欧元
2 money = iter(bag) #给工人取名代号money,把麻袋交给工人iter()
3 print(money)#看看工人的情况 
4 
5 #显示结果
6 <list_iterator object at 0x10b032898>
7 #工种(数据type类型)  与   工人岗位地址(内存地址)

就此,工人准备就绪,这样就生成了一个随时开工数钱的对象,这样的对象就叫可迭代对象,同时这个对象也是一个数钱工具,也就是迭代器。

下命令给工人开始数钱吧 用__next__()方法来数钱

print(money.__next__()) #命令员工先数一张钱
#显示结果
$
print(money.__next__())#再数一张
#显示结果
¥
print(money.__next__())#再数一张
#显示结果
£
print(money.__next__())#再来数一张
#显示结果
print(money.__next__())#再来数一张
#显示结果报错
StopIteration #员工说麻袋空了,还让我数什么?

__next__()方法的命令,只能让工人一个个数,而且数光了,每次都要呼叫老板报错,老板要被这不动脑的工人给烦死了。

其实可以提前给工人一本操作手册,指导工人的作业规范,这里就可以用 for 命令来当操作手册

1 for i in money:
2     print(i)
#显示结果

$
¥
£

这下不报错了,老板解放了。

老板寻思着,光有一个取钱工人数钱不行啊,前数后忘记,还是得再雇一个记录员,取钱工每取一次钱报给记录员,记录员依次记录下来报告给老板,老板叫停就得停,叫继续就得继续,

记录员如果报错了,就得从头再来报一次。

这个按规矩办事的记录员就是 我们接下来要说的 生成器

 1 #记录员把每次取钱的记录按顺序备案
 2 count1 = money.__next__()
 3 count2 = money.__next__()
 4 count3 = money.__next__()
 5 count4 = money.__next__()
 6 
 7 #老板吩咐记录员逐一汇报
 8 def bossOrder():
 9     yield count1 #汇报一次停一次
10     yield count2 #汇报一次停一次
11     yield count3 #汇报一次停一次
12     yield count4 #汇报一次停一次
13 
14 report = bossOrder()
15 #开始逐一汇报给老板
16 print(report.__next__())
17 >>$
18 #老板说继续
19 print(report.__next__())
20 >>¥
21 #老板又说继续
22 print(report.__next__())
23 >>£
24 #老板满意地说继续吧
25 print(report.__next__())
26 >>€

就此我们看到,记录员(生成器)的工作性质与 取钱工(迭代器)基本一致,只是生成器变得更听老板话,更灵活多变了。

生成器 也是 迭代器的一种。

有一天有一个脑子转特别快的小伙子看到这老板怎么那么傻雇了两个人干这活,就对老板说,给两个人80%的工资,他一个人能干两个人的活。

老板说,那么你先试试看行不行

#小伙子说,给我一麻袋钱,我数钱还能听您吩咐
smartBoy = (x for x in bag) #加上()就能做成生成器
#老板说开始汇报
print(smartBoy.__next__())
>>$
#老板说继续
print(smartBoy.__next__())
>>¥
#老板说继续
print(smartBoy.__next__())
>>£
#老板说继续
print(smartBoy.__next__())
>>print(type(smartBoy))
#显示结果
>><class \'generator\'>
print(type(report))
#显示结果
>><class \'generator\'>
#两者类型都是生成器

老板定睛一看,这小伙记性好,干活麻利,就是他了!

以上我们可以发现,制作生成器有两种方式,一种使用yield,一种使用()。

 

总结:

我觉得迭代器的作用其实就是为了节省计算机内存而设计的,一个迭代器本质上就是一个数学公式寄存在内存中,需要用时,通过公式生成数据。

这样做,加快了计算机的运行速度,简化了内存占有空间,让程序跑得更顺畅。

 

以上是关于Python基础滚固故弄玄虚的迭代器与生成器的主要内容,如果未能解决你的问题,请参考以下文章

Python高手之路python基础之迭代器与生成器

python基础理解迭代器与生成器

python 基础之迭代器与生成器

python基础-函数之装饰器迭代器与生成器

python-迭代器与生成器1

Python3 迭代器与生成器