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,一种使用()。

总结:

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

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

原文地址:https://www.cnblogs.com/yydada/p/11740991.html

时间: 2024-11-14 12:44:18

Python基础滚固(八)故弄玄虚的迭代器与生成器的相关文章

Python入门篇(八)之迭代器和生成器

迭代器和生成器 1.列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式.举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)): >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环: >

Python基础滚固(六)深浅拷贝的趣谈

先来探究下浅拷贝 1 a = [1000, [2000, 3000]] 2 b = a.copy() #来个拷贝 3 print(a is b) 4 print(id(a), id(b)) 5 print(id(a[0]) == id(b[0]), id(a[1]) == id(b[1])) #检查第一层每个序列的id是否一致 6 7 #输出结果 8 False #a 与 b 不是同一个 9 4556627912 4557461256 #a b各自id也不一样 10 True True #a b

Python基础滚固(二)有意思的 else

我们在 if 语句中经常使用 else 来做分支判断,今天发现 循环语句 for,while 也可以使用 else 语句来做分支. 1 for i in range(3): 2 print(i) 3 else: 4 print("Good!") 5 6 #输出 可以看出循环遍历后 执行了else语句 7 0 8 1 9 2 10 Good! 11 12 #增加 break 13 for i in range(3): 14 print(i) 15 break 16 else: 17 pr

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

1. 函数嵌套 1.1 函数嵌套调用 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数 def bar(): print("from in the bar.") def foo(): print("from in the foo.") bar() foo() 1.2 求函数最大值 def max2(x,y): if x > y: return x else: return y def max4(a,b,c,d): res1 = max2(a,b) re

Python核心编程的四大神兽:迭代器、生成器、闭包以及装饰器

生成器 生成器是生成一个值的特殊函数,它具有这样的特点:第一次执行该函数时,先从头按顺序执行,在碰到yield关键字时该函数会暂停执行该函数后续的代码,并且返回一个值:在下一次调用该函数执行时,程序将从上一次暂停的位置继续往下执行. 通过一个例子来理解生成器的执行过程.求1-10的所有整数的立方并将结果打印输出,正常使用列表的实现如下: 输出结果如下: 当数据量很少时,可以很快得到结果.但是如果范围扩大到10000甚至是100000000,就会发现程序执行时间会变长,变卡,甚至有可能会因超出内存

Python基础day-8[装饰器补充,迭代器(未完)]

wraps模块: 让函数保留原来的说明信息. 在闭包函数上面 @wraps 可以把原代码的解释,引用到装饰器中,让用户彻底无法感知装饰器的存在 使用 func.__doc__ 和 print(help(func))来查看函数的注释信息 from functools import wraps import time def coutime(func): @wraps(func) #调用wraps模块 def wrapper(*args,**kwargs): # 'a1231231231231232

【Python基础学习篇八】Python函数

函数是一段可以重复多次调用的代码,通过输入的参数值,返回需要的结果. 一.函数的定义 函数的定义使用保留字def定义.函数在使用前必须定义,函数的类型即返回值的类型. Python函数定义的格式如下: def 函数名 (参数1[=默认值1],参数2[=默认值2]...): ... return 表达式 函数名可以是字母.数字或下划线组成的字符串,但不能以数字开头.函数的参数放在一对圆括号中,参数的个数可以有一个或多个,参数之间用逗号隔开,这种参数称之为形式参数. 例子: #!/usr/bin/e

python基础教程(八)

创建自已的对象(类)是python非常核心的概念,事实上,python被称为面向对象语言,本章会介绍如何创建对象.以及面向对象的概念:继承.封装.多态. 多态: 可对不同类的对象使用同样的操作. 封装:对外部世界隐藏对象的工作细节. 继承:以普通的类为基础建立专门的类对象. 多态 面向对象程序设计最有趣的特性是多太,它是是让大多数人犯晕的特性.所以,先来介绍这个. 多态意思是"有多种形式".多态意味着就算不知道变量所引用的对象类是什么,还是能对它进行操作,而它也会根据对象(或类)类型的

python学习笔记-(八)装饰器、生成器&amp;迭代器

本节课程内容概览: 1.装饰器 2.列表生成式&迭代器&生成器 3.json&pickle数据序列化 1. 装饰器 1.1 定义: 本质上是个函数,功能是装饰其他函数—就是为其他函数添加附加功能 1.2 装饰器原则: 1)  不能修改被装饰函数的源代码: 2)  不能修改被装饰函数的调用方式: 1.3 实现装饰器知识储备: 1.3.1 函数即“变量” 定义一个函数相当于把函数体赋值给了函数名 变量可以指向函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15