• 迭代器、生成式、生成器


    目录:

      迭代器

      生成器

      生成式

      三元表达式

      for循环原理

    概要:

    生成式:一次性生成所有数据,然后保存在内存中,适合小量数据
    生成器:返回一个可迭代对象,生成器generator对象,必须通过遍历才能一一将值取出
    生成器不会一次列出所有的数据,next()一次,给一个值,更加节省内存使用率
    可迭代对象(iterable):可以通过for循环调用出来的,就是可迭代对象,如:列表、元组、字典、生成式、生成器
    迭代器(iterator):任何具有__next__()方法的对象都是迭代器,对迭代器调用next()方法可以获取下一个值

    迭代器:

    1. 什么是迭代器 
        迭代指的是一个重复的过程,每一次重复都是基于上一次的结果而来的
          迭代器指的是迭代取值的工具,该工具的特点是可以不依赖于索引取值
    #原始的迭代方法
        li=['a','b','c','d','e']
        li=('a','b','c','d','e')
        li='hello'
    
        i=0
        while i < len(li):
            print(li[i])
            i+=1

    2. 为何要用迭代器
    为了找出一种通用的&可以不依赖于索引的迭代取值方式

    3. 如何用迭代器
    可迭代的对象:但凡内置有.__iter__方法的对象都称之为可迭代的对象
    迭代器对象:既内置有__iter__方法,又内置有__next__方法
    关于__iter__方法:
    调用可迭代对象的__iter__会得到一个迭代器对象
    调用迭代器对象的__iter__会得到迭代器本身

    4. 总结迭代器的优缺点:
    优点:
    1. 提供了一种通用的&可以不依赖于索引的迭代取值方式
    2. 同一时刻在内存中只有一个值,更加节省内存(老母鸡,Python3的rang()方法就相当于一只老母鸡)

    缺点:
    1. 取指定值不如索引灵活,并且迭代器是一次性的
    2. 无法预知迭代器数据的个数
    迭代器对象:

      可迭代的对象: str,list,tuple,dict,set,文件对象(除了数字类型)
      迭代器对象: 文件对象
      可迭代的对象=====》迭代器对象:调用可迭代对象内置的__iter__方法会有一个返回值,该返回值就是对应的迭代器对象
    #基本语法
    dic={'x':1,'y':2,'z':3} iter_dic=dic.__iter__() print(iter_dic) #<dict_keyiterator object at 0x0000000001D97728> res1=iter_dic.__next__() print(res1) #x
    res2=iter_dic.__next__()
    print(res2)

    res3=iter_dic.__next__()
    print(res3)
    #超出迭代器数据个数,报错
    res4=iter_dic.__next__()
    print(res4)
    print(dic.__iter__().__next__())#x
    print(dic.__iter__().__next__())#x
    print(dic.__iter__().__next__())#x

    通过循环来捕捉异常,避免取值越界后报错:
     1 dic={'x':1,'y':2,'z':3}
     2 # dic=['a','b','c']
     3 iter_dic=dic.__iter__()
     4 
     5 iter_dic=open(r'今日内容',mode='rt',encoding='utf-8')#文件为迭代器对象
     6 
     7 while True:
     8     try:
     9         print(iter_dic.__next__())
    10     except StopIteration:
    11         break

     for循环原理:

    for准确地说应该是迭代器循环,for循环的原理如下:
      1. 先调用in后面那个值的__iter__方法,得到迭代器对象
      2. 执行迭代器.__next__()方法得到一个返回值,然后赋值给一个变量k,运行循环体代码
      3. 循环往复,直到迭代器取值完毕抛出异常然后捕捉异常自动结束循环
     1 dic={'x':1,'y':2,'z':3}
     2 iter_dic=dic.__iter__()
     3 print(iter_dic)
     4 print(iter_dic.__iter__())
     5 
     6 for k in dic: # iter_dic=dic.__iter__() | k=iter_dic.__next__()
     7     print(k)
     8 # <dict_keyiterator object at 0x0000000000477728>
     9 # <dict_keyiterator object at 0x0000000000477728>
    10 # x
    11 # y
    12 # z
    with open(r'今日内容',mode='rt',encoding='utf-8') as f:
    for line in f: #iter_f=f.__iter__()
    print(line)

     自定义迭代器:

    yield关键字:只能用在函数内
      在函数内但凡包含有yield关键字,再去执行函数,就不会立刻运行函数体代码了,会得到一个返回值,该返回值称之为生成器对象,生成器本质就是迭代器

    总结yield:
      1. 提供一种自定义迭代器的解决方案
      2. yield可用于返回值

    yield VS return

    相同点:都可以用于返回值
    不同点:yield可以暂停函数,yield可以返回多次值,而return只能返回值一次值函数就立刻终止

     1 def func():
     2     print('=====>第一次')
     3     yield 1
     4     print('=====>第二次')
     5     yield 2
     6     print('=====>第三次')
     7     yield 3
     8     print('=====>第四次')
     9 
    10 g=func()
    11 print(g.__iter__().__iter__().__iter__() is g)
    12 iter(g) #g.__iter__()
    13 res=next(g) #g.__next__()
    14 print(res)
    15 
    16 res1=next(g)
    17 print(res1)
    18 
    19 res2=next(g)
    20 print(res2)
    21 
    22 res3=next(g)     #报错,取不到
    23 print(res3)
    24 # True
    25 # =====>第一次
    26 # 1
    27 # =====>第二次
    28 # 2
    29 # =====>第三次
    30 # 3
    31 # =====>第四次
     自定义一个rang函数:
    def my_range(start,stop,step=1):
        while start < stop:
            yield start
            start+=step
    
    res=my_range(1,5,step=2) # 1 3
    print(next(res))    #1
    print(next(res))    #3
    for item in res:     #还在同一个迭代器中,此时res已经到3,步长为2,没有下一个值
        print(item)     #打印不到结果
    
    
    for item in my_range(1,5,2):    #这是一个新的迭代器
        print(item)    #1,3

    三元表达式:

    原始操作:
    def max2(x,y):
        if x > y:
            return x
        else:
            return y
    
    简化操作:
    x=10
    y=20
    res=x if x > y else y
    print(res)

    XXX生成式:

     列表生成式:列表

    将大于4的数字添加到egg后,存入列表:

    #原始操作:
    l=[]
    for i in range(1,11):
        if i > 4:
            res='egg%s' %i
            l.append(res)
    print(l)
    #简化操作:
    l=['egg%s' %i for i in range(1,11) if i > 4]
    print(l)
    #['egg5', 'egg6', 'egg7', 'egg8', 'egg9', 'egg10']

     将除了egon外的名字后加上_DSB,然后存入一个列表:

    #原始操作:
    names=['egon','lxx','yyx','cw','alex','wxx']
    l=[]
    for name in names:
        if name != 'egon':
            res='%s_DSB' %name
            l.append(res)
    print(l)
    #简化操作:
    l=['%s_DSB' %name for name in names if name != 'egon']
    print(l)
    #['lxx_DSB', 'yyx_DSB', 'cw_DSB', 'alex_DSB', 'wxx_DSB']

    字典生成式:字典

    items=[('name','egon'),('age',18),('sex','male')]
    #原始方法: dic={} for k,v in items: dic[k]=v print(dic)
    #简化方法: res={k:v for k,v in items if k != 'sex'} print(res)   #{'name': 'egon', 'age': 18} res={i for i in 'hello'} print(res)
    #{'o', 'h', 'e', 'l'} 去重,逐个,无序

    生成器表达式(实际也是一个迭代器):

    res=(i**2 for i in range(3))
    print(res)    #本身是一个迭代器,只有调用next方法,才能取到值,什么也不会打印
    print(next(res))
    print(next(res))
    print(next(res))
    #0
    #1
    #4
     1 with open(r'今日内容',mode='rt',encoding='utf-8') as f:
     2     data=f.read()
     3     print(len(data)) #1025
     4 
     5 with open(r'今日内容', mode='rt', encoding='utf-8') as f:
     6     res=0
     7     for line in f:
     8         res+=len(line)
     9     print(res)#1025
    10 
    11 with open(r'今日内容',mode='rt',encoding='utf-8') as f:
    12     res=sum((len(line) for line in f))
    13     # res=sum(len(line) for line in f)#有双重小括号,可以省略一个
    14     print(res)
    15 
    16 with open(r'今日内容', mode='rt', encoding='utf-8') as f:
    17     res=max([len(line) for line in f])  #60
    18     #res=max((len(line) for line in f))  #60
    19     #res=max(len(line) for line in f)    #60
    20     print(res)

     

  • 相关阅读:
    vue 手动挂载 $amount()
    Redis 主从配置
    DMA分区管理
    C# 构造函数里的base和this的区别
    SQL Server 数据库性能优化
    TCP和UDP的优缺点及区别
    Django框架初步应用简述
    前端vue框架应用雏形
    接口mock之moco
    python进阶(九)~~~协程、进程池、线程/进程/协程对比
  • 原文地址:https://www.cnblogs.com/xuechengeng/p/9721314.html
Copyright © 2020-2023  润新知