当前位置: 首页 > 后端技术 > Python

小白学Python(21):生成器基础

时间:2023-03-25 21:46:13 Python

人生苦短,我选择Python。Python(三):基本数据类型(下)初学Python(四):变量的基本操作初学Python(五):基本运算符(上)初学Python(六):基本运算符(上)2)小白学习Python(七):流程控制基础(上)小白学习Python(八):流程控制基础(二)小白学习Python(九):数据结构基础(列表)(上)小白学习Python(10):数据结构基础(列表)(下)小白学习Python(11):数据结构基础(元组)小白学习Python(12):数据结构基础(字典)(上)小白学习Python(13):数据结构基础(词典)(下)小白学Python(14):数据结构基础(集)(下)小白学Python(15):数据结构基础(集)(下)小白学Python(16):基本数据类型(函数)(上)小白学习Python(17):基本数据类型(函数)(下)小白学习Python(18):基本文件操作小白学习Python(18):Basic文件操作小白学习Python(19):异常处理基础小白学习Python(20):迭代器生成器基础前面我们讲了为什么要用迭代器,大家应该还有印象(说有就过分了不起来)。如果列表太大,会占用太多内存。您可以使用迭代器只取出需要使用的部分。生成器的设计原理与迭代器类似。如果你需要一个非常大的集合,你不会把所有的元素都放在这个集合中,而是将元素保存为生成器的状态,每次迭代返回一个值。比如我们要生成一个列表,可以使用如下方法:list1=[x*xforxinrange(10)]print(list1)结果如下:[0,1,4,9,16,25,36,49,64,81]如果我们生成的列表非常庞大,例如:list2=[x*xforxinrange(1000000000000000000000000)]结果如下:Traceback(mostrecentcall最后):文件“D:/Development/Projects/python-learning/base-generator/Demo.py”,第3行,在list2=[x*xforxinrange(10000000000000000000000000)]文件“D:/Development/Projects/python-learning/base-generator/Demo.py",line3,inlist2=[x*xforxinrange(1000000000000000000000000)]MemoryError报错,报错信息提示我们存储异常,整个程序跑了很久。友情提示,创建这么大的列表请慎重,如果电脑配置不够,可能会卡机。如果我们用generator的话会很方便,而且执行速度飞快。generator1=(x*xforxinrange(10000000000000000000000))print(generator1)print(type(generator1))结果如下:at0x0000014383E85B48>然后,我们使用generator以后如何读取generator产生的数据呢?当然和前面的迭代器一样,使用next()函数:generator2=(x*xforxinrange(3))print(next(generator2))print(next(generator2))print(next(generator2)))print(next(generator2))结果如下:Traceback(mostrecentcalllast):File"D:/Development/Projects/python-learning/base-generator/Demo.py",line14,在打印(next(generator2))StopIteration直到结束,抛出StopIteration异常。但是这种使用方式我们并不知道迭代什么时候结束,所以我们可以使用for循环获取每个生成器生成的具体元素,使用for循环而不用关心最后的StopIteration异常。generator3=(x*xforxinrange(5))forindexingenerator3:print(index)结果如下:014916generator很强大,本质上generator并没有取和存我们具体的元素,它存储的是计算算法,通过算法计算出下一个值。如果计算算法比较复杂,不能用类似列表生成的for循环实现,也可以用函数实现。比如我们定义一个函数,emmmmmmm,简单点吧,大家懂的精神:defprint_a(max):i=0whilei这里使用了关键字yield,yield和return很相似,都可以返回一个值,不同的是yield不会结束函数。我们多次调用这个用函数创建的生成器:print(next(a))print(next(a))print(next(a))print(next(a))结果如下:1234可以看到当我们在使用next()对生成器进行操作时,会返回一个循环的值,并在yield中结束本次运行。但是下次执行next()时,会从上一个断点继续运行。直到下一个yield,并不断重复直到生成器结束。还有一个等同于next()的方法,直接看示例代码:print(a.__next__())print(a.__next__())结果如下:56接下来要介绍的方法就更厉害了,不仅可以迭代,还可以传一个值给函数:defprint_b(max):i=0whilei