• Python迭代器、生成器


      python中经常用到迭代,但是对于迭代器、生成器一直处于模糊的理解,查看了不少资料,感觉有些清晰了。

      什么是迭代

      通过for循环不断的拿到list中的值就是迭代,迭代就是循环做重复的事情。

    for i in range(10):
        print(i)
    

       可以通过for循环进行迭代的对象称为可迭代对象(Iterable),如何判断是否是可迭代对象,可以用collection模块中的Iterable来判断

    >>> from collections import Iterable
    >>> isinstance([],Iterable)
    True
    >>> isinstance("",Iterable)
    True
    >>> isinstance({},Iterable)
    True
    >>> isinstance(123,Iterable)
    False
    >>> isinstance((),Iterable)
    True
    

       可迭代对象内部都实现了_iter_方法,例如list,通过help(list)查看

    |  __iter__(self, /)
    |      Implement iter(self).

      可迭代对象可以通过循环拿到值,但是可迭代对象不是迭代器。

      迭代器

      为什么list、dict、str等数据类型不是Iterator?这是因为Python的迭代器(Iterator)对象表示的是一个数据流,迭代器(Iterator)对象可以被next() 函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

          迭代器(Iterator)甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
      迭代器可以通过next函数不断计算下一个数据。

    >>> c=iter(b)
    >>> c
    >>> next(b)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'list' object is not an iterator
    >>> next(c)
    0
    

       可以看到list是可迭代对象,但是无法使用next函数,因为它不是迭代器,而c则可以

      创建迭代器的方法

      可以通过 iter(list/set..) 来把一个可迭代对象创建为迭代器。

      生成器

      生成器可以理解为特殊的迭代器,它也实现了iter和next方法,也是基于计算的迭代,一边计算一边迭代的机制称为generator

      创建生成器的方法

      1. 通过列表推导式,把列表生成式的[]改为()

    >>> g=(x for x in range(10))
    >>> type(g)
    <class 'generator'>
    

       2.通过生成器函数得到一个生成器,定义一个包含yield的函数,普通函数中通过return返回值,返回后整个函数已经结束,而生成器函数中通过yield返回值,返回后会记录yield的位置,然后下次再调用会从yield的位置继续执行

    def func(n):
        a=1
        for i in range(n):
            yield a
            a+=i
    
    a=func(5)
    print(a)
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    

       看下结果,返回的是一个生成器,可以通过next函数不断拿到值,直到抛出StopIteration

      总结:

    1. 可迭代对象不一定是迭代器

    2.迭代器一定是可迭代对象

    3.实现了__next__函数(或可以通过next函数取值),__iter__函数的是迭代器

    4.生成器是特殊的迭代器,可以通过列表推导式或者函数中使用yield来获得生成器

  • 相关阅读:
    [Windows]wmic查看运行进程的参数
    Java8中的foreach跳出循环break/return
    Python Learning(6)字典
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(三): 整合阿里云 OSS 服务 -- 上传、下载文件、图片
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(四): 整合阿里云 短信服务、整合 JWT 单点登录
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑
    Servlet、Jsp
    BIO、NIO、AIO
    HashMap (JDK1.8) 分析
    mysql常见笔试题
  • 原文地址:https://www.cnblogs.com/dreamyu/p/11906525.html
Copyright © 2020-2023  润新知