可迭代对象、迭代器、生成器

可迭代对象

  • 可迭代对象(对象:python中一切皆对象,一个实实在在存在的值,对象。迭代:重复的,循环的一个过程,更新迭代每一次都有新的内容)

    • 字面意思
      • 可以进行循环更新的一个实实在在的值
    • 专业角度
      • 内部含有__iter__方法的对象,被成为可迭代对象
  • 获取对象的所有方法并且以支付串的形式表示

    • dir()

    • 判断一个对象是否是可迭代对象

      #方法一
      s1='ghj'
      s=dir(s1)
      
      for i in s:
          if "iter" in i:
              print('ok')
              
      #方法二
      print('__iter__' in dir('fghj'))
      
  • 小结

    • 优点:
      • 存储的对象直接能显示,比较直观
      • 拥有的方法比较多,操作方便
    • 缺点:
      • 占内存
      • 不能直接通过for循环,不能直接取值(索引,key除外)

迭代器

  • 迭代器的定义(器:可更新迭代的工具。)

    • 字面意思:可更新迭代的工具
    • 专业角度:内部含有__iter__方法并且含有__next__方法的对象就是迭代器
  • 可以判断是否是迭代器__iter__and __next__在不在dir(对象 )

    • with open('简单',encoding='utf-8',mode='r')as f1:
          print('__iter__'in dir(f1)and'__next__' in dir(f1))
      
  • 迭代器取值

    • s='ghjkl'
      a=iter(s)
      print(next(a))
      print(next(a))
      print(next(a))
      
  • 可迭代对象转换成迭代器

    1.iter(可迭代对象)

  • while循环模拟for 循环机制

    s=[11,22,33,44,55,66]
    a=iter(s)
    while True:
        try:
            print(next(a))
        except StopIteration:
            break
    
  • 小结(优缺点)

    • 优点:
      • 节省内存
      • 惰性机制(next一次取一个值,绝对不多取)
        • 迭代时数据处理的基石,扫描内存中放不下的数据集时,我们要找到一种惰性获取数据的方式,即按需一次获取一个数据项,这就是迭代器模式。
    • 缺点:
      • 速度慢
      • 不走回头路

可迭代对象和迭代器对比

  • 可迭代对象
    • 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少的一个数据集(几百万数据8G内存是可以承受的)
    • 应用:当侧重于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择
  • 迭代器
    • 迭代器是一个节省内存,可以记录取值的位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集
    • 应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为主要因素时,将数据集设置为迭代器是一个不错的选择(可以参考python为什么把文件句柄设置为迭代器)

生成器

  • 什么是生成器

    • python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。
    • 生成器与迭代器的区别:生成器是我们自己用代码构建的一种数据结构,迭代器都是提供或者转化过来的。
  • 获取生成器的三种方式

    • 生成器函数

      • return和yield的区别:

        • return:函数中只存在一个return结束函数并且给函数的执行者返回值
        • yield:只要函数中有yield那么它就是生成器而不是函数了
        • 生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next。
        • 生成yield函数以上得代码会执行,以下的代码则不会执行
        def func():
            print('aaa')
            print('bbb')
            yield 3
            print('ccc')
            yield 6
            print('ddd')
        ret=func()
        print(next(ret))
        print(next(ret))
        
        得:
        aaa
        bbb
        3
        ccc
        6
        
    • 生成器表达式

      • 不用一次性全取,需要多少取多少
      def bao():
          for i in range(1,201):
              yield i
      ret=bao()
      for j in range(50):
          print(next(ret))
      
    • python内部提供的一些

  • yeild form

    • yield from 将l1这个列表变成迭代器返回
    def func():
        li=[11,22,33,44]
        yield from li    #yield from 将l1这个列表变成迭代器返回
    ret=func()
    print(next(ret))
    
  • 生成器表达式

    • 与列表推导式的写法几乎一模一样
    obj=(i for i in range(1,11))
    for j in obj:       #for 循环的时候就已经转换成迭代器
      print(j)
    
    
    
    obj=(i for i in range(1,11))
    print(next(obj))
    print(next(obj))
    print(next(obj))
    

posted @ 2021-06-03 13:31  刘家小仙女  阅读(60)  评论(0编辑  收藏  举报