1.迭代器
(1).迭代器的相关介绍
什么是迭代器?
迭代:指一个重复的过程,每次的迭代都必须基于上一次的结果。’
迭代器:迭代取值的工具。
为什么要用?
迭代器给你提供了一种不依赖于索引取值的方式。
需要迭代器的数据类型有:字符串,列表,元组,字典,集合。
# 重复+每次迭代都是基于上一次的结果而来的 s = 'hello' n = 0 while n < len(s): print(s[n]) n +=1 >>>:输出结果跟 for i in s print(i) 一致
(2).可迭代对象
只要内置有__iter__方法的都叫做可迭代对象。针对双下划线开头双下划线结尾的方法,推荐读法为 双下+方法名。
基本数据类型中是可迭代对象的又:字符串,列表,字典,元组,集合。
文件对象(执行内置的__iter__之后还是本身,没有任何变化):文件对象本身就是迭代器对象。
res = l.__iter__() # res = iter(l)
可迭代对象执行内置的--iter--方法得到的就是该对象的迭代器对象。
2.迭代器取值
(1).内置有__inter__方法
(2).迭代器取值一定要用__next__方法
补充:迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象。
d = [1,2,3,4] iter_d = d.__iter__() #将可迭代器对象d装换成迭代器对象 print(iter.__next__()) #迭代器取值 ,调用 print(iter.__next__()) # 一行只能取一个值 print(iter.__next__()) #如果取完了以后再取,直接报错StopIteration
f1 = open(f'xxx.txt','r',encoding='utf-8') #调用f1内置的__iter__方法 iter_f = f1.__iter__() print(iter_f is f1) #迭代器对象无论执行多少次__iter__方法,得到的都还是迭代器对象本身 print(f1 is f1.__iter__().__iter__().__iter__().__iter__())
迭代器取值的特点:只能完后依次取,不能后退
3.for循环的本质
d = {'name':'li','password':'123','hobby':read'} print i in d: print(i) # for循环后面的in关键词,跟的是一个可迭代对象for
for循环内部的本质:
(1).将in后面的对象调用__iter__转换成迭代器对象。
(2).调用__next__迭代取值。
(3).内部有异常捕获topIteration,当__next__报出这个错误,循环自动结束循环
可迭代对象:内置有__iter__方法的。
迭代器对象:既内置有__iter__也内置有__next__方法
迭代取值的优缺点
优点:不依赖于索引值,内存中永远只占一份空间,不会导致内存溢出。
缺点:不能够获取指定的元素,取完之后会报StopIteration错。
4.生成器
生成器:常指用户自己所定义的迭代器。所有的生成器都是迭代器,因为生成器对象有 __iter__
和 __next__
方法,且 __iter__
方法返回自身
def func(): print('first') yield 666 # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行 print('second') yield 777 #yield后面跟的值就是调用迭代器__next__方法你能得到的值 #yield既可以返回一个值也可以返回多个值,并且多个值也是按照元组的形式返回 g = func() # 生成器初始化:将函数变成迭代器 print(g) #>>>:<generator object func at 0x00000214D9AFCF10>生成器对象func位于这个地址内 print(g.__next__()) print(g.__next__())
补充:生成器不会主动执行任何一行代码,必须要通过__next__才能触发代码运行。
5.yield的用法
yield支持外界为其传参,并且能提供一种自定义生成器方式,可以将函数的运行状态给暂停住,有返回值。
def func(name): print('%s 准备开吃') while True: food = yield #当函数内有yield关键字的时候,调用该函数不会执行函数体代码 print('%s 吃了 %s'%(name,food)) g = func('li') #将函数变成来生成器 g.__next__() #必须先将代码运行至yield才能够为其传值 g.send('饺子') # 给yield左边的变量传参,相当于触发了__next__方法
与return的异同之处
相同点:都可以返回值,并且都可以返回多个
不同点:yield可以返回多次值,而retrun只能返回一次就立即结束;yield可以接受外部传入的值。