三.函数迭代器,生成器,内置函数

迭代器:
定义:更新换代的过程 每次迭代都必须基于上一次的的结果
器:迭代取值的工具
特点:不依赖索引取值
迭代取值的数据类型:字符串,列表,元组,字典,集合
一,可迭代对象
1,可迭代对象:只有内置有__iter__方法的都叫做可迭代对象
2,是可迭代对象的有: str list tuple dict set
文件对象(执行内置的__iter__之后还是本身 没有任何变化)
文件对象本身就是迭代器对象
案例: res = s.__iter__() # res = iter(s)
print(s.__len__()) # 简化成了len(s)
res1 = l.__iter__() # res1 = iter(l)
res2 = f1.__iter__() # res2 = iter(f1)
重点:可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象
二:迭代器对象
1,内置有__iter__方法
2,内置有__next__方法 (进行取值)
注意:迭代器对象一定是可迭代对象
而可迭代对象不一定是迭代器对象
必须满足1,2 两个条件才是迭代器对象
1》生成一个可迭代对象
l = [1,2]
res = l.__iter__()
# 就是把一个可迭代对象用.__iter__()方法生成迭代器对象
2》迭代器取值 调用 __next__()
print(res.__next__()) # 1
# 调用依次取出一个元素(迭代器对象中有几个元素就可以调用几次)
直到取完,就会报错StopIteration
案列:
f1 = open('xxx.txt','r',encoding='utf-8')
调用f1内置的__iter__方法
iter_f = f1.__iter__()
print(iter_f is f1) # 判断iter_f 是不是 f1 ,打印 True 或者 False

重点:1,迭代器对象的取值必须用 __next__()
2,迭代器对象无论执行多少次__iter__方法,得到的还是迭代器对象本身
# print(f1 is f1.__iter__().__iter__().__iter__().__iter__())
3. 迭代器取值的特点: 只能往后依次取值,不能倒着取
**注意:4,可迭代对象转为迭代对象用一次 .__iter__() 就可,多次调用和第一次调用一样(可以理解为初始化)
5,调用一次.__next__()方法只能取出其中一个元素,(列表为第一个值,字典取出的是key)
总结:
可迭代对象:内置有__iter__方法的
迭代器对象: 既 内置有__iter__ 也内置有__next__方法

迭代取值:优点:不依赖索引取值
内存中始终都占一份空间,不会导致内存溢出
缺点
1.不能够获取指定的元素,只能从前往后依次取
2.取完之后会报StopIteration错

案例:1,文件取值案列
(假如文件中有一行内容,如果有n行就调用n次iter_f.__next__()
f = open('xxx.txt','r',encoding='utf-8')
iter_f = f.__iter__()
print(iter_f.__next__())
2,可迭代对象取值(list,dict,set,tuple,str)
l = [1,2,3,4]
iter_l = l.__iter__()
print(iter_l.__next__()) # 1

l2 = {'name':'jason'}
iter_l2 = l2.__iter__()
print(iter_l2.__next__()) # name

l3 = (3,'sr',[1,2],{1,'sc'})
iter_l3 = l3.__iter__()
print(iter_l3.__next__()) # 3
print(iter_l3.__next__()) # sr
print(iter_l3.__next__()) # [1, 2]
print(iter_l3.__next__()) # {1, 'sc'} 其中的元素是什么类型,取出来的也是该数据类型

三:for循环的本质:
for i in d: # for循环后面的in关键 跟的是一个可迭代对象
1.将in后面的对象调用__iter__转换成迭代器对象
2.调用__next__迭代取值
3.内部有异常捕获StopIteration,当__next__报这个错 自动结束循环
四:生成器:
用户自定义的迭代器,本质就是迭代器
1,函数内有yield关键字存在时,函数名加括号不会运行函数体的代码块
而是将它转变为生成器,当用.__next__() 方法时才会走函数体代码
2,函数体代码运行遇到yield 就会暂停运行
3,yield后面跟的值就是调用迭代器__next__方法你能得到的值 ********
4, yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
5,yield 支持外界为其传参,多个值时 是以元组的形式返回
案列:
def func():
print('egon not is dsb')
yield 'no'
print('天上飞来一只猴')
yield '666'
g = func() # 生成器初始化:将函数变成迭代器
g.__next__() ## egon not is dsb
print(g.__next__()) #天上飞来一只猴 666
注意:函数体代码中有 yield,当函数名加括号调用时,
他就是将函数转变为了自定义的生成器,并不会立即执行函数体代码
案列:
def func(name):
print('%s 准备开吃'%name)
while True:
food = yield
print('%s 吃了 %s'%(name,food))
g = func('egon')
g.__next__() # 必须先将代码运行至yield 才能够为其传值 #egon 准备开吃
g.send('天天向上') # 给yield左边的变量传参 触发了__next__方法 # egon 吃了 天天向上
g.send('好好学习') #egon 吃了 好好学习
2,生成器表达式:

res = (i for i in range(1,100000000) if i != 4) # 生成器表达式
print(res)
1,生成器不会主动执行任何一行代码
2,必须通过__next__触发代码的运行zcf
四:内置函数
divmod 分页器
print(divmod(101,10)
enumerate 枚举
exec(s)
eval(s)
eval不支持逻辑代码
format 三种玩法
{}占位
{index} 索引
{name} 指名道姓

isinstance 后面统一改方法判断对象是否属于某个数据类型
n = 1
print(type(n))
print(isinstance(n,list)) # 判断对象是否属于某个数据类型

l = [0,1,0]
print(all(l)) # 只要有一个为False就返回False
print(any(l)) # 只要有一个位True就返回True
补充:
异常处理:
while True:
try:
print(iter_d.__next__())
except StopIteration:
print( ’取完了,没有了')
break
原文地址:https://www.cnblogs.com/Fzhiyuan/p/11191596.html