一.迭代器
1.什么是迭代器?
迭代取值的工具
2.为什么要用迭代器?
在不利用for循环取值的情况下,我们分别对 字符串,列表,字典,元组,集合进行取值。我们发现字典和集合无法取值,因为他们俩都是无序的,不能利用索引取值,所以这时候我们就用到了迭代器。
迭代器给我们提供了一种不依赖索引取值的方式
3.如何用迭代器?
首先引入一个可迭代对象概念
只有内置有__iter__方法的都叫做可迭代对象
__iter__ 读作 双下+方法名
在基本数据类型中可迭代对象有:str list tuple dict set 文件对象
之后我们就可以再介绍迭代器对象
1.内置有__iter__方法
2.内置有__next__方法
ps:迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象
#生成一个迭代器对象 l = [1,2,3,4] iter_l = l.__iter__() #迭代器取值 调用__next__ print(iter_l.__next__()) print(iter_l.__next__()) print(iter_l.__next__()) print(iter_l.__next__()) print(iter_l.__next__()) #如果取完了,就会报错
f1 = open('xxx.txt','r',encoding = 'utf-8') #调用f1 内置的__iter__方法 iter_f =f1.__iter__() print(iter_f is f1) #True
迭代器对象无论执行多少次__iter__方法得到的还是迭代器本身(********)
上面有个问题,如果取多了里面没有值了的话,就会报错
下面我们进行异常处理
while True: try: print(iter_d.__next__()) except StopIteration: break
迭代器取值的特点: 只能往后依次取,不能后退
for循环的本质
for循环内部的本质
1.将in后面的对象调用__iter__转换成迭代器对象
2.调用__next__迭代取值
3.内部有异常捕获StopIteration,当__next__报这个错,自动循环结束
下面总结一下迭代器:
可迭代对象:内置有__iter__方法的
迭代器对象:既内置有__iter__也内置有__next__方法
迭代取值:
优点
1.不依赖于索引取值
2.内存中永远只占一份空间,不会导致内存溢出
缺点
1.不能够获取指定的元素
2.取完之后会报StopIteration错
二.生成器
1.什么是生成器?
用户自定义的迭代器,本质就是迭代器
def func(): print('first) yield 666 print('second') yield 777 pirnt('third') yield 888 print('forth') yield # yield后面跟的值就是调用迭代器__next__方法你能得到的值 # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回 g = func() print(g) print(g.__next__) print(g.__next__) print(g.__next__) print(g.__next__) print(g.__next__)
例子:
for i in range(1,10,2): print(i)
将上面的写成一个生成器
def my_range(start,end,step=1) while start<end: yield start start+=step for j in my_range(1,10,2) print(j)
yield 表达式形式
yield支持外界为其传参
def dog(name): print('%s 准备开吃'%name) while True: food = yield print('%s吃了%s' %(name,food))
当函数内有yield关键字的时候,调用该函数不会执行函数体代码。而是将函数变成生成器
g = dog('egon')
g.__next__() 必须先将代码运行至yield 才能够为其传值
g.send('包子') 给yield左边的变量传参 同时出发__next__()方法
yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值
与return之间异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值
生成器表达式
res = (i for i in range(1,100000000) if i != 4) print(res)
生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行(*********)
面向过程编程
面向过程编程:就类似于设计一条流水线
好处:将复杂的问题流程化 从而简单化
坏处:可扩展性较差 一但需要修改,整体都会受到影响