迭代器:
迭代的工具。迭代是更新换代,如你爷爷生了你爹,你爹生了你,迭代也可以说成是重复,并且但每一次的重复都是基于上一次的结果来的。如计算机中的迭代开发,就是基于软件的上一个版本更新。以下代码就不是迭代,它只是单纯的重复
可迭代对象
python中一切皆对象,对于这一切的对象中,但凡有__iter__方法的对象,都是可迭代对象。
可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。
迭代器对象
只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。 在找到该方法前,首先我们给出迭代器对象的概念:可迭代的对象执行__iter__方法得到的返回值。并且可迭代对象会有一个__next__方法。 一定次数后要是__next__() 调用超出上限会导致无值可取 报错StopIteration 但是在我们可以使用while循环精简下。其中使用的try...except...为异常处理模块
总结
迭代器对象:执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。
特点:
内置__next__方法,执行该方法会拿到迭代器对象中的一个值
内置有__iter__方法,执行该方法会拿到迭代器本身
文件本身就是迭代器对象。
缺点:
取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
无法使用len()方法获取长度
for循环原理
for循环称为迭代器循环,in后必须是可迭代的对象。
将in后面的对象调用__iter__转换成迭代器对象
调用__next__迭代取值
内部有异常捕获StopIteration,当__next__报这个错 自动结束循环
迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身(******)
迭代器取值的特点
1.只能往后依次取 不能后退
特别注意类型:文件类型
文件类型本身就是一个迭代器对象 问:__iter__方法就是用来帮我们生成迭代器对象 而文件对象本身就是迭代器对象,为什么还内置有__iter__方法??? 解答:for 循环 时候必须要有__iter__方法 这是必须步骤 ,所以~~~~ # f = open('xxx.txt','r',encoding='utf-8') # iter_f = f.__iter__() # print(iter_f.__next__()) # print(iter_f.__next__()) # print(iter_f.__next__()) # print(iter_f.__next__()) # print(iter_f.__next__())
生成器
yield
1.帮你提供了一种自定义生成器方式
2.会帮你将函数的运行状态暂停住
3.可以返回值
与return之间异同点
相同点:都可以返回值,并且都可以返回多个
不同点:
yield可以返回多次值,而return只能返回一次函数立即结束
yield还可以接受外部传入的值
用户自定义的迭代器,本质就是迭代器
生成器的自主yield 传值
# def func(): # print('first') # yield 666 # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行 # print('second') # yield 777 # print('third') # yield 888 # print('forth') # yield # yield # # yield后面跟的值就是调用迭代器__next__方法你能得到的值 # # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回 # g = func() # 生成器初始化:将函数变成迭代器 # print(g) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__())
迭代yield生成后取数例子
def my_range(start,end,step=1): while start < end: yield start start += step for j in my_range(1,100,2): print(j)
yield支持外界为其传参
def dog(name):
print('%s 准备开吃'%name)
while True:
food = yield
print('%s 吃了 %s'%(name,food))
# def index():
# pass
# 当函数内有yield关键字的时候,调用该函数不会执行函数体代码
# 而是将函数变成生成器
# g = dog('egon')
# g.__next__() # 必须先将代码运行至yield 才能够为其传值
# g.send('狗不理包子') # 给yield左边的变量传参 触发了__next__方法
# g.send('饺子')
生成式表达式
()
# 生成器不会主动执行任何一行代码
# 必须通过__next__触发代码的运行
列子如
# res = (i for i in range(1,100000000) if i != 4) # 生成器表达式 # print(res) # f = open('xxx.txt','r',encoding='utf-8') # data = f.read() # print(len(data)) # f.close() # with open('xxx.txt','r',encoding='utf-8') as f: # # n = 0 # # for line in f: # # n += len(line) # # print(n) # g = (len(line) for line in f) # # print(g.__next__()) # # print(g.__next__()) # # print(g.__next__()) # # print(g.__next__()) # print(sum(g))
列子
生成器和迭代器的结合面试题
还有要注意 list() list分为3步骤 转化为 迭代器对象 然后迭代 然后添加入列表 他会执行__next__ 会把老母鸡的蛋给偷走!!!!!!!!!!!!!!!!!!!!!!!!!