迭代器和生成器
Posted zh-xiaoyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器和生成器相关的知识,希望对你有一定的参考价值。
一、迭代器
1、什么是迭代?
迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来
2、要想了解迭代器到底是什么?必须先了解一个概念,即什么是可迭代的对象?
可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象
字符串,列表,元组,集合,字典都是可迭代的
#以下都是可迭代的对象 # str1=‘hello‘ # list1=[1,2,3] # tup1=(1,2,3) # dic={‘x‘:1} # s1={‘a‘,‘b‘,‘c‘} # f=open(‘a.txt‘,‘w‘,encoding=‘utf-8‘)
3、迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象
dic={‘x‘:1,‘y‘:2,‘z‘:3} iter_dic=dic.__iter__() print(iter_dic) print(iter_dic.__next__()) print(iter_dic.__next__()) print(iter_dic.__next__()) # print(iter_dic.__next__()) #报错 StopIteration ‘‘‘ <dict_keyiterator object at 0x02E5FC60> x y z ‘‘‘ s1={‘a‘,‘b‘,‘c‘} iter_s1=s1.__iter__() print(iter_s1.__next__()) print(iter_s1.__next__()) print(iter_s1.__next__()) print(iter_s1.__next__()) #报错 StopIteration ‘‘‘ b c a ‘‘‘
4、可迭代的对象vs迭代器对象?
可迭代的对象:str,list,tuple,dict,set,file 1、获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象 2、特点: 内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象 迭代器对象:文件对象本身就是迭代器对象 1、获取迭代器对象的方式: 执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象 2、特点: 内置有__next__方法,执行该方法会拿到迭代器对象中的一个值 内置有__iter__方法,执行该方法会拿到迭代器本身
5、迭代器优缺点分析
#5.1 迭代器的优点: #5.1.1、提供了一种可不依赖于索引的取值方式 l=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) iter_l=l.__iter__() while True: try: print(iter_l.__next__(),end=‘‘) except StopIteration: break#5.1.2 迭代器更加节省内存 item=range(0,10000000000000000000) print(item) #5.2迭代器的缺点: #5.2.1、取值麻烦,只能一个一个取,只能往后取, #5.2.2、并且是一次性的,无法用len获取长度 x=[1,2,3] iter_x=x.__iter__() while True: try: print(iter_x.__next__()) except StopIteration: break
6、for循环原理分析
(1) for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
(2) for循环会执行in后对象的__iter__方法,拿到迭代器对象
(3) 然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
(4) 周而复始,直到取值完毕,for循环会检测到异常自动结束循环
# l=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) # for line in l: #iter_l=l.__iter__() # print(line) for item in {‘x‘:1,‘y‘:2}: print(item)
二、生成器
(1) 函数内包含有yield关键字, (2) 再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
(3) 生成器的本质就是迭代器,其用法和迭代器类似
示例:
def chicken(): print(‘=====>first‘) yield 1 print(‘=====>sencond‘) yield 2 print(‘=====>third‘) yield 3 obj=chicken() print(obj) #<generator object chicken at 0x03032830> #1、iter_obj=obj.__iter__(),拿到迭代器 #2、iter_obj.__next__(),拿到该方法的返回值,赋值给item #3、周而复始,直到函数内不在有yield,即取值完毕 #4、for会检测到StopIteration异常,结束循环
小节:
1、为我们提供了一种自定义迭代器的方式,
可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次
因为yield可以保存函数执行的状态
小示例:
def eat(name): print(‘%s ready to eat‘ %name) food_list=[] while True: food=yield food_list # food=‘骨头‘ food_list.append(food) #food_list=[‘泔水‘,‘骨头‘] print(‘%s start to eat %s‘ %(name,food)) dog1=eat(‘bw‘) #1、必须初始化一次,让函数停在yield的位置 res0=dog1.__next__() print(res0) #2、接下来的事,就是喂狗 #send有两方面的功能 #1、给yield传值 #2、同__next__的功能 res1=dog1.send(‘苹果‘) print(res1) res2=dog1.send(‘橘子‘) print(res2) res3=dog1.send(‘西瓜‘) print(res3) ‘‘‘ bw ready to eat [] bw start to eat 苹果 [‘苹果‘] bw start to eat 橘子 [‘苹果‘, ‘橘子‘] bw start to eat 西瓜 [‘苹果‘, ‘橘子‘, ‘西瓜‘] ‘‘‘
以上是关于迭代器和生成器的主要内容,如果未能解决你的问题,请参考以下文章