迭代器与生成器

末鹿安然 提交于 2019-12-04 20:21:54
  • [ ] ```python
    https://www.cnblogs.com/zhangchaocoming/p/11192436.html
    https://www.cnblogs.com/liangmingshen/p/10970534.html

    可迭代对象

    内置有__iter__方法的对象,例如字符串,列表,字典,元组等等都是可迭代对象

    迭代器对象

    1. 既内置有__next__方法的对象,执行迭代器__next__方法可以不依赖索引取值
    2. 又内置有__iter__方法的对象,执行迭代器__iter__方法得到的仍然是迭代器本身

    通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

      所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator

      生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

      生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器

    res=(i+1 for i in range(10))#res就是一个生成器
    for i in res:
        print (i)

    python中生成器
    要创建一个generator,有很多种方法,第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator

    所以我们创建一个generator后,基本上永远不会调用next(),而是通过for循环来迭代,并且不需要关心StopIteration的错误,generator非常强大,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

    for循环(也称之为迭代器循环)的工作原理:

    1,先调用in后面那个对象的__iter__的方法,将其变成一个迭代器对象‘
    
    2,调用next(迭代器),将其得到的返回值赋值给变量名K,

      3,循环往复直到next(迭代器)抛出异常,for会自动捕捉异常,然后结束循环。   

               dic={'x':1,'y':2,'z':3}
    
                 for k in dic:
                     print(k)

    python提供了两种基本的方式

    生成器函数:也是用def定义的,利用关键字yield一次性返回一个结果,阻塞,重新开始

    生成器表达式:返回一个对象,这个对象只有在需要的时候才产生结果

    1.生成器函数
    为什么叫生成器函数?因为它随着时间的推移生成了一个数值队列。一般的函数在执行完毕之后会返回一个值然后退出,但是生成器函数会自动挂起,然后重新拾起急需执行,他会利用yield关键字关起函数,给调用者返回一个值,同时保留了当前的足够多的状态,可以使函数继续执行,生成器和迭代协议是密切相关的,迭代器都有一个__next__()__成员方法,这个方法要么返回迭代的下一项,要买引起异常结束迭代。

    函数有了yield之后,函数名+()就变成了生成器

    return在生成器中代表生成器的中止,直接报错

    next的作用是唤醒并继续执行

    send的作用是唤醒并继续执行,发送一个信息到生成器内部

    '''生成器'''

    def create_counter(n):
    print("create_counter")
    while True:
    yield n
    print("increment n")
    n +=1

    gen = create_counter(2)
    print(gen)
    print(next(gen))
    print(next(gen))

    结果:
    <generator object create_counter at 0x0000023A1694A938>
    create_counter
    2
    increment n
    3
    Process finished with exit code 0

    2.生成器表达式

    迭代器总结:
    优点:
    1,提供一种通用的且不依赖索引的迭代取值的方式
    2,同一时刻在内存中只存在一个值,更节省内存。
    缺点:
    1,取值不如按照索引的方式灵活,(不能区指定的某一个值而且取值是从左往右,)
    2,无法预测迭代器的长度,取完之后会报stopiteration错

    二,生成器:用户自定义的迭代器,本质就是迭代器。优点:节省内存(如果数据量较大,最好不要用列表生成式),代码量更少,执行更高效。

    ```

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!