zoukankan      html  css  js  c++  java
  • 迭代器、生成器

    1.迭代器:迭代工具

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

    lst = ['a','b','c']
    n = 0
    while n < len(n):
        print(lst[n])
        n += 1
    

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

    #以下都是可迭代的对象
    str1='hello'            
    list1=[1,2,3]
    tup1=(1,2,3)
    dic={'x':1}
    s1={'a','b','c'}
    f=open('a.txt','w',encoding='utf-8')
    

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

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

    1.2可迭代的对象vs迭代器对象

    '''
    可迭代的对象:str,list,tuple,dict,set,file
    1、获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
    2、特点:
        内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
    
     迭代器对象:文件对象本身就是迭代器对象
    1、获取迭代器对象的方式:
        执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
    2、特点:
        内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
        内置有__iter__方法,执行该方法会拿到迭代器本身
    '''
    

    文件本身就是迭代器对象

    1.3迭代器的优缺点分析

    '''
    1 迭代器的优点:
    1.1 提供了一种可不依赖于索引的取值方式
    1.2 迭代器更加节省内存
    2.迭代器的缺点:
    2.1 取值麻烦,只能一个一个取,只能往后取
    2.2 并且是一次性的,无法用len获取长度
    '''
    

    1.4for循环原理分析

    '''
    1. for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
    2. for循环会执行in后对象的__iter__方法,拿到迭代器对象
    3. 然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
    4. 周而复始,直到取值完毕,for循环会检测到异常自动结束循环
    '''
    
    lst = [1,2,3,4,5,6]
    new_lst = lst.__iter__()
    while True:
        try:
            print(new_lst.__next__())
         except StopIteration:
            break
    

    2.生成器

    2.1函数内包含有yield关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象

    # 生成器本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法
    def chicken():
        print('啦啦啦')
        yield 1
        print(123)
        yield 2
        print(456)
        yield 3
        print(798)
    res = chicken()
    res1 = res.__next__()
    print(res1)
    res.__next__()
    res.__next__()
    
    '''
    # 1. iter_res=res.__iter__(),拿到迭代器
    # 2. 出发iter_res.__next__(),拿到该方法的返回值,赋值给item
    # 3. 周而复始,直到函数内不在有yield,即取值完毕
    # 4. for会检测到StopIteration异常,结束循环
    '''
    for item in res:
    	print(item)
    

    总结yield:

    # 1. 为我们提供了一种自定义迭代器的方式,可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
    # 2. yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次,因为yield可以保存函数执行的状态
    
    def my_range(start,stop,step=1):
        n=start
        while n < stop:
            yield n #yield 4
            n+=step #5
    
    obj=my_range(3,7,2) #3,5,
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    
    for item in my_rangr(5,10,2):
        print(item)
    

    2.2yield的表达式

    def eat(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list # food='骨头'
            food_list.append(food) # food_list=['泔水','骨头']
            print('%s start to eat %s' %(name,food))
    
    dog1=eat('狗')
    
    # 1. 必须初始化一次,让函数停在yield的位置
    res0=dog1.__next__()
    print(res0)
    # 2. 接下来的事,就是喂狗
    
    # send有两方面的功能
    # 1. 给yield传值
    # 2. 同__next__的功能
    res1=dog1.send('泔水')
    print(res1)
    res2=dog1.send('骨头')
    print(res2)
    res3=dog1.send('shit')
    print(res3)
    
    
    lst = [1,2,3,4,5,6]
    def func():
        yield from lst
    g = func()
    for i in g:
        print(i)
    

    2.3整理

    # 在函数中将return改写成yield就是一个生成器
    # yield 会记录执行位置
    # return 和 yield 都是返回,
    # return 可以写多个,但是只执行一次,yield可以写多个,还可以返回多次
    # 一个__next__() 对应 一个yield
    # 生成器可以使用for循环获取值
    # yield from -- 将可迭代对象元素逐个返回
    # 在函数的内部 yield 能将for循环和while循环进行临时暂停
    

    3.推导式

    lst = []
    for i in range(10):
        lst.append(i)
    print(lst)
    

    3.1list 推导式

    lst = [i for i in range(10)]    # list 推导式
    

    3.2循环模式

    # [变量 for i in range(20)]
    print([i+1 for i in range(10)])
    

    3.3筛选模式

    lst = []
    for i in range(20):
        if i % 2 == 0:
            lst.append(i)
    print(lst)
    
    print([i for i in range(20) if i % 2 == 0])
    # [变量(加工后的变量) for循环 加工方式]
    
    print([i for i in range(50) if i % 2 == 1])
    print([i for i in range(1,50,2)])
    

    4.生成器表达式

    4.1循环模式

    # 生成器表达式:
    # (变量(加工后的变量) for循环)
    # (变量(加工后的变量) for循环 加工条件)
    g = (i for i in range(20))
    print(next(g))
    print(next(g))
    print(next(g))
    print(list((i for i in range(20))))
    

    4.2筛选模式

    g = (i for i in range(50) if i % 2 == 1)
    for i in g:
        print(i)
    

    4.3字典推导式:(了解)

    # {键:值 for循环 加工条件}
    print({i:i+1 for i in range(10)})
    print({i:i+1 for i in range(10) if i % 2 == 0})
    

    4.4集合推导式:(了解)

    # {变量(加工后的变量) for循环 加工条件}
    print({i for i in range(10)})
    print({i for i in range(10) if i % 2 == 0})
    
  • 相关阅读:
    小程序mpvue使用scroll-view
    mysql之join浅析
    YApi-v1.9.2部署失败(Accessing non-existent property 'count' of module exports inside circular dependency)的解决方案
    YApi 可视化部署时遇到9090端口被占用时的解决方案
    [转载]最近涉及字符串列表存储,为加快检索速度,搜集了一些哈希函数,C语言的代码保存见内
    字符串的编码检测
    mbcs、unicode,UTF-8、UTF-16等的转换
    支持多重结构的配置信息读取代码,基于VS2008
    配置信息读取代码(VS2012编译通过,使用了C++11特性)
    [转载]TCPMP0.72RC1的编译与移植以及自己另外做UI完整方法
  • 原文地址:https://www.cnblogs.com/fengqiang626/p/11213016.html
Copyright © 2011-2022 走看看