漫天飞雪

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
# 迭代器
#     迭代器是一个重复的过程,每次取值都是基于上一次的结果,而进行迭代取值的工具
#
#       拥有:
#             __iterator__  和 __next__内置方法
#       注意:
#             1.重复取值,单纯的重复取值的不是迭代器对象
#             2.每次取值都是基于上次取值结果而进行
#
#         作用:
#             提供了一种不依赖于索引的迭代取值的方式
#
#         分类:
#             可迭代的对象:list tuple dict set
#             迭代器对象:file 生成器 内置有iter next方法

                # 实例:
                # l=[1,2,3,4,5,6]
                # iter_l=l.__iter__()#调用可迭代的对象__iter__得到一个新的迭代器对象

                # print(iter_l.__next__())#迭代1次
                # print(iter_l.__next__())#迭代2次
                # print(iter_l.__next__())#迭代3次
                # 按照next的次数依次的输出结果,有几个next就输出几次结果
                #是依据上次的迭代结果一次进行next结果输出
                #因为只产生了依次iter_l=l.__iter__(),下面的next的输出都是按照这个迭代对象
                # 依次的输出

                # 错误方式:
                # print(l.__iter__().__next__())#迭代1次
                # print(l.__iter__().__next__())#迭代2次
                # print(l.__iter__().__next__())#迭代3次
                # 输出结果:
                # 1
                # 1
                # 1
                # 因为进行迭代时,每次都是l列表产生新的迭代器的对象,都是重新进行next,是一个单纯的重复的过程

                # 注:之所以可迭代对象和迭代器对象都有iter,和next的方法,是为了进行统一,迭代机制统一。
    #
    # 总结:
    #     优点:
    #         1.提供一种不依赖索引的取值方式
    #         2.同一时刻内存中只存在一个值,而且只能往后去
    #     缺点:
    #         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') 迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象 dic={'x':1,'y':2,'z':3} iter_dic=dic.__iter__() print(iter_dic.__next__()) print(iter_dic.__next__()) print(iter_dic.__next__()) print(iter_dic.__next__()) 可迭代的对象vs迭代器对象 可迭代的对象:str,list,tuple,dict,set,file(文件本身就是迭代器) a、获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象 b、特点: 内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象 迭代器对象:文件对象本身就是迭代器对象 #迭代器对象一定是可迭代对象 a、获取迭代器对象的方式: 执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象 b、特点: 内置有__next__方法,执行该方法会拿到迭代器对象中的一个值 内置有__iter__方法,执行该方法会拿到迭代器本身 iter_x=x.__iter__() iter_x.__next__() print(iter_x.__iter__().__iter__().__iter__().__iter__() is iter_x) #拿到的还是本身 迭代器的优缺点分析 迭代器提供了一种可不依赖于索引的取值方式(优点) #字典无序,没有办法通过索引取值,可通过迭代器取值 l=open('a.txt','r',encoding='utf-8') iter_l=l.__iter__() while True:   try:   print(iter_l.__next__())   except StopIteration:   break 迭代器更加节省内存(优点)#迭代器本身是一个内存地址 #range在python2中是一个列表,在python3中是一个迭代器 取值麻烦,只能一个一个取,只能往后取(缺点) 并且是一次性的,无法用len获取长度(缺点) for循环原理分析 a、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象 #while 循环称为条件循环 b、for循环会执行in后对象的__iter__方法,拿到迭代器对象 c、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体 d、周而复始,直到取值完毕,for循环会检测到异常自动结束循环 for line in l: #iter_l=l.__iter__()   print(line) for item in {'x':1,'y':2}:   print(item) 生成器:函数内包含有yield关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象 def chicken():   print('=====>first')   yield 1   print('=====>sencond')   yield 2   print('=====>third')   yield 3   obj=chicken()   res=obj.__next__()   print(res)   res1=obj.__next__()   print(res1)   res2=obj.__next__()   print(res2) 1、iter_obj=obj.__iter__(),拿到迭代器 2、触发iter_obj.__next__(),拿到该方法的返回值,赋值给item 3、周而复始,直到函数内不在有yield,即取值完毕 4、for会检测到StopIteration异常,结束循环 for item in obj:   print(item) 总结yield:   1、为我们提供了一种自定义迭代器的方式,可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器   2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次。因为yield可以保存函数执行的状态 def my_range():   print('start........')   n=0   while True:   yield n   n+=1   obj=my_range()   print(obj)   print(obj.__next__())   print(obj.__next__())   print(obj.__next__())   print(obj.__next__())   for i in my_range():   print(i) def my_range(start,stop,step=1):   n=start   while n < stop:   yield n #yield 4   n+=step #5 obj=my_range(3,7,2) #3,5, print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) for item in my_range(5,10,2):   print(item) 生成器之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('alex') 1、必须初始化一次,让函数停在yield的位置 res0=dog1.__next__()   print(res0) 2、接下来的事,就是喂狗 send有两方面的功能   a、给yield传值   b、同__next__的功能 res1=dog1.send('泔水')   print(res1) res2=dog1.send('骨头')   print(res2) res3=dog1.send('shit')   print(res3)

 

posted on 2018-12-26 19:59  漫天飞雪世情难却  阅读(102)  评论(0编辑  收藏  举报