• 迭代器与生成器


    迭代:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来

    while True:
        print('=------->')
    
        l=[1,2,3,4,5,6]
        n=0
        while n < len(l):
            print(l[n])
            n+=1
    这个循环就是每次重复都是基于上一次的结果而来。

    2、要想了解迭代器到底是什么,就必须先了解一个概念。即什么是可迭代的对象?

    可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代对象 

    以下都是可迭代的对象   它们的内置中都有__iter__方法。

    字符串:  str='hello'
    列表:    list=[1,2,3]
    元组:    tup1=(1,2,3)
    字典:    dic={'x':1}
    集合:     s1={'a','b','c'}
    文件:    f=open('a.txt','w',encoding='utf-8')

    用法如下:

     dic={'x':1,'y':2,'z':3}
     iter_dic=dic.__iter__()

    3、迭代器对象:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象。

           以下是迭代器对象。

          特点是他们都带有__next__的方法。


    列表 list1=[1,2,3]
    字典 dic
    ={'x':1,'y':2,'z':3} 集合 s1={'a','b','c'}


    如下:

    dic={'x':1,'y':2,'z':3}
    iter_dic=dic.__iter__()
    iter_dic.__next__())

    4、可迭代的对象VS 迭代器对象?

    可迭代的对象:str,    list,    tuple,   dic,     set,     file

    1、获取可迭代对象的方式:无须获取,python内置:str,    list,    tuple,   dic,     set,     file都是可迭代对象。

    2、特点:

    内置__iter__方法都叫可迭代的对象,执行该方法会拿到一个迭代器对象

    迭代器对象:文件对象本身就是迭代器对象

    1、获取迭代器对象的方式:

    执行可迭代对象的__iter__的方法,拿到的返回值就是迭代器对象

    2:特点:

    内置有__next__方法,该执行方法会拿到迭代器对象中的一个值

    内置有__iter__方法,执行该方法会拿到迭代器本身

    迭代器的优缺点

    1、迭代器的优点

    1、提供了一种可以不依赖于索引的取值方式

    l=open('a.txt','r',encoding='utf-8')
    iter_l=l.__iter__()
    while True:
        try:   
            print(iter_l.__next__())
        except StopIteration:
            break

    2、迭代器更加节省内存

    同样 有优点  就有缺点,

    缺点1:取值麻烦,只能一个一个取,只能往后取,

    缺点2:并且是一次性,无法用len获取长度。

    3、for 循环原理分析:

    1:for循环称之为迭代器循环,in后跟的必须是可迭代的对象:

    2:for循环会执行in后对象的__iter__方法,拿到迭代器对象。

    3:然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体。

    4:周而复始,直到取值完毕, for循环会检测到异常自动结束循环。

    生成器:

    函数内包yield 关键字,

    再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象

    def chicken():
        print('=====>first')
        yield 1   #保函 yield,到这个yield后暂停不动,这个1就是返回值,也是              生成器的对象
        print('=====>sencond')
        yield 2
        print('=====>third')
        yield 3
    
    
    obj=chicken()

    生成器的本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法。

    所以他的循环也是遵循迭代器用法

    def chicken():
        print('=====>first')
        yield 1 
        print('=====>sencond')
        yield 2
        print('=====>third')
        yield 3
    
    
    obj=chicken()
    
    for item in obj:
        print(item)
    
    #打印结果:
    =====>first
    1
    =====>sencond
    2
    =====>third
    3
    
    #第一步 iter_obj=obj.__iter__(),拿到迭代器,
    第2步;出发iter_obj._next_(),拿到该方法的返回值,赋值给item,
    第3步 周而复始,直到函数内不再有yield,即取值完毕。
    第4步,for会检测导StopIteration异常,结束循环。

    总结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)
    for i in my_range():
        print(i)
    
    
    #打印结果
    1
    2
    3
    4
    5
    6
    7
    8
    。
    。
    。
    。
    。
    。
    一直到无穷大。就是因为yield只是暂停。

    3、生成器yield的表达形式:

    第一步、必须初始化一次, 让函数停在yield的位置,

    第二部:然后在send给yield传值, send有两个作用, 一个给yield传值,一个是当__next__的功能使用。

    def eat(name):
        print('%s ready to eat'%name)
        food_list=[]
        while True:
            food =yield
            food_list.append(food)
            print('%s start to %s'%(name,food))
    
    dog1=eat('alex')
    res0=dog1.__next__()     #第一次 先调用__next__(),让函数停在这里
    # print(res0)
    res1=dog1.send('')      #然后send给yield传值。
    
    #打印结果
    alex ready to eat
    alex start to 肉
    ['']
    alex start to 麻辣烫
    ['', '麻辣烫']
  • 相关阅读:
    jsp开发环境搭建(windows64位)
    python环境和工具
    判断单链表是否有环及寻找环的入口
    Eclipse实用操作
    img标签在div里上下居中
    继承小结
    创建对象
    方法链、作用域链和原型链(三)——原型链
    python截取字符串
    在vscode上运行python
  • 原文地址:https://www.cnblogs.com/lx3822/p/8684620.html
Copyright © 2020-2023  润新知