迭代器与生成器
#迭代器的特点:
# 1.一个个取值,不是一次性把所有数据都创建出来
# 2.只能按照顺序取,不能回头
# 3.迭代器中的数据,不取不创建
# 4.迭代器中的数据只能从头到尾取一次
#可迭代协议:如果一个数据中有iter方法,那么这个数据是一个可迭代的类型
#迭代器协议:如果一个数据中有iter方法和next方法,那么这个数据是一个迭代器的类型
# ran=range(3) # iter_=ran.__iter__() #把range变成一个迭代器 # print(iter_) #返回内存地址 # print(iter_.__next__()) #一个一个取值 # print(iter_.__next__()) # print(iter_.__next__()) # print(iter_.__next__()) #超出范围了 StopIteration
迭代器特点:
节省内存空
除了文件操作符,学过的所有内容都不是迭代器,除了整型、浮点数、布尔值,其他都是可迭代的
#False 不可迭代 # print('__iter__' in dir(123)) #dir(123) 整型包含的方法 # print('__iter__' in dir(True)) # print('__iter__' in dir(12.4)) #可迭代的 # print('__iter__' in dir('123')) # print('__iter__' in dir([1,2,'4'])) # print('__iter__' in dir({1:2})) # print('__iter__' in dir((1,2))) # print('__iter__' in dir({1,2,3})) # print('__iter__' in dir(range(5))) # f=open('a.txt',encoding='utf-8') # print('__iter__' in dir(f)) #迭代器 只有f,其他都不是 # print('__next__' in dir('123')) # print('__next__' in dir([1,2,'4'])) # print('__next__' in dir({1:2})) # print('__next__' in dir((1,2))) # print('__next__' in dir({1,2,3})) # print('__next__' in dir(range(5))) # iter_=ran.__iter__() #把range变成一个迭代器 # print('__next__' in dir(iter_)) # f=open('a.txt',encoding='utf-8') #文件操作符是一个迭代器 # print('__next__' in dir(f))
for 循环没有迭代器就循环不了
for循环的底层代码(了解)
# lst=[1,2,3,4,5] # iter_=lst.__iter__() # while True: # try: # print(iter_.__next__()) # # except StopIteration: # break
生成器
生成器本质就是迭代器
生成器:
生成器函数:只要包含yield关键字,这个函数就是生成器函数
生成器表达式(结果 for 变量 in 可迭代对象 if 条件筛选)
# def func(): # print(111) # yield 222 #yield分段来执行一个函数 # print(333) # yield 444 # # ret=func() # print(ret) #内存地址 # print(ret.__next__()) # print(ret.__next__()) # print(ret.__next__()) #StopIteration 报错 #第一种 # def func2(): # lst=[] # for i in range(1000): # lst.append('校服'+str(i)) # return lst # # ret3=func2() # print(ret3) #一次性创建所有的,占内存 #使用生成器 # def func2(): # lst=[] # for i in range(1000): # yield '校服'+str(i) # # ret3=func2() # print(ret3.__next__()) #取值 # print(ret3.__next__()) # print(ret3.__next__()) # print(ret3.__next__()) #区别:第一种一次性把数据全部拿出来,占内存,第二种使用生成器,一次取一个,你要多少取多少
send 和next 区别
send 和next都是让生成器向下走一次
send是可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器函数时,不能使用send,必须使用next
def eat(): print('今天吃什么') a=yield '面条' print('a',a) b=yield '干煸四季豆' print('b',b) yield 'GAME OVER' gen=eat() print(gen) #内存地址 print(gen.__next__()) #print(gen.__next__()) ret1=gen.send('麻辣烫') print(ret1) ret2=gen.send('狗粮') print(ret2)
浙公网安备 33010602011771号