函数迭代器与生成器

it2022-05-05  203

迭代器

什么是迭代器?

  迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果

  迭代器:迭代取值的工具

为什么要用?

  迭代器给你提供了一种不依赖与索引取值的方式

n = 0 while True: print(n) #这就是不算是迭代器,只是简单的重复 l = [1,2,3,4] s = 'hello' n = 0 while n < len(s): print(n) n+=1 #重复+每次迭代都是基于上一次的结果而来的

需要迭代取值的数据类型:

  字符串

  列表

  元组

  字典

  集合

可迭代对象:只要内置有__iter__方法的都叫做可迭代对象

基本数据类型中是可迭代的对象有:

  str    list    tuple  set   dict

  文件对象(执行内置的__iter__之后还是本身   没有任何变化):文件对象本身就是迭代器对象

s = 'hello' l = [1,2,34,] t = (1,2,34) s1 = {1,2,3,4} d = {'name':'jason'} f1 = open('xxx.txt','w',encoding='utf-8') res = s.__iter__() # res = iter(s) print(s.__len__()) # 简化成了len(s) res1 = l.__iter__() # res1 = iter(l) res2 = f1.__iter__() # res2 = iter(f1) print(res,res1,res2) print(f1)

可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象

 

迭代器的取值

迭代器对象:

  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__()) #如果取完了 直接报错 d = {'name':'yzy','sex':'male'} #将可迭代对象d转换成迭代器对象 iter_d = d.__iter__() #迭代器对象的取值必须用__next__ print(iter_d.__next__()) print(iter_d.__next__()) print(iter_d.__next__()) #取完了 报错StopIteration

迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本事(******)

d = {'name':'jason','password':'123','hobby':'泡m'} iter_d = d.__iter__() #异常处理 while True: try: print(iter.d__next__()) except StopIteration: print('no') break d = {'name':'jason','password':'123','hobby':'泡m'} iter_d = d.__iter__() #异常处理 while True: try: print(iter.d__next__()) except StopIteration: print('no') break

迭代器取值的特点:

  只能往后依次取,不能后退

Ps:可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象

d = {'name':'jason','password':'123','hobby':'泡m'} for i in d: print(i) #for循坏后面的in关键 跟的是一个可迭代对象

 for循坏内部的本质

  1.将in后面的对象调用__iter__转换成迭代器对象

  2.调用__next__迭代取值

  3.内部有异常捕获StopIteration,当__next__报这个错  自动结束循坏

可迭代对象:内置有__iter__方法

迭代器对象:既内置有__iter__也有内置__next__方法

迭代取值:

  优点:

    1.不依赖与索引取值

    2.内存中永远只占一份空间,不会导致内存溢出

  缺点:

    1.不能够获取指定的元素

    2.取完之后会报StopIteration错

生成器

  用户自定义的迭代器,本质上就是迭代器

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 dog(name): print('%s 准备开吃'%name) while True: food = yield print('%s 吃了 %s'%(name,food)) 当函数内有yield关键字的时候,调用该函数不会执行函数体代码 而是将函数变成生成器 g = dog('yyy') g.__next__() # 必须先将代码运行至yield 才能够为其传值 g.send('apple') # 给yield左边的变量传参 触发了__next__方法

yield

  1.帮你提供了一种自定义生成器方式

  2.会帮你将函数的运行状态暂停

  3.可以返回值

与return之间的异同点:

  相同点:都可以返回值,都可以返回多个

  不同点:

    yield可以返回多次值,而return只能返回一次函数立即结束

    yield还可以接受外部传入的值

生成器表达式

res = (i for i in range(1,100) if i != 4) #生成器表达式 #生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行 print(res.__next__()) print(res.__next__()) print(res.__next__()) print(res.__next__()) with open('name.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(sum(g))

常用的内置方法

abs()#求绝对值

abs(-1)

print(bin(10)) #2进制 print(oct(10)) #8进制 print(hex(10)) #16进制 print(int('0b1010',2) #将2进制转换成10进制 callable()#判断是否可调用 print(chr(97))#将数字转换成ascii码表对应的字符 print(ord('a')) #将字符按照ascii表转成对应的数字 dir 获取当前对象名称空间里面的名字 l = [1,2,3] print(dir(l)) divmod 分页器 print(divmod(100,10)) total_num,more = divmod(900,11) if more: total_num += 1 print('总页数:',total_num) enumerate 枚举 l = ['a','b'] for i,j in enumerate(l,1): print(i,j) eval exec s = """ print('hello baby') x = 1 y = 2 print(x+y) """ eval(s) exec(s) #eval 不支持逻辑代码,只支持一些简单的python代码 isinstance 判断对象是否属于某个数据类型 n = 1 print(inistance(n,int)) pow print(pow(2,3)) #8 round print(round(3.4)) # 3 print(round(3.6)) #4

面向过程编程:就类似与设计一条流水线

  好处:

    将复杂的问题流程化  从而简单化

  坏处:

    可扩展性较差  一旦需要修改   整体都会受到影响

转载于:https://www.cnblogs.com/KrisYzy/p/11190156.html


最新回复(0)