• day13 python学习 迭代器,生成器


    1.可迭代:
    当我们打印

    print(dir([1,2]))   在出现的结果中可以看到包含

    '__iter__',  这个方法,#次协议叫做可迭代协议

    包含'__iter__'方法的函数就是可迭代函数
    字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的


    2.迭代器 iterator
    l = [1,2,3,4]
    l_iter = l.__iter__()  #迭代器的生成
    item = l_iter.__next__()    #迭代器的使用,用此方法一一钓鱼迭代器中的数值
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    #迭代器取值的三种方法
    1.item.__next() 传统方法

    2 在for循环中取值
    for i in range(10):
      print(item.__next__()) #取出里边的10个值
    for i in item.__next__()  #将里边所用的值在循环中取出
      print(i)


    3. print(list(item)) 用 list 方法强转成列表在迭代器中取出值


    这是一段会报错的代码,如果我们一直取next取到迭代器里已经没有元素了,就会抛出一个异常StopIteration,告诉我们,列表中已经没有有效的元素了。

    这个时候,我们就要使用异常处理机制来把这个异常处理掉。

    l = [1,2,3,4]
    li=l.__iter__()
    while True:
            try:
                item=li.__next__()
                print(item)
            except StopIteration:#这里要输入的是报错的内容  ,出现这个错误时执行以下内容
    print('超出索引') break

    3.判断是否是迭代器

    print('__next__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__   当他为真时证明是可迭代的,
    print('__iter__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__   当两个结果都为True时,就是迭代器
    
    from collections import Iterator
    print(isinstance(range(100000000),Iterator))  #验证range执行之后得到的结果不是一个迭代器

    4.生成器

    如果在某些情况下,我们也需要节省内存,就只能自己写。我们自己写的这个能实现迭代器功能的东西就叫生成器。

    Python中提供的生成器:

    1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行

    2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

     

    生成器Generator:

      本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)

      特点:惰性运算,开发者自定义

    生成器函数

    一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

    def func():   #这就是一个简单的生成器函数
        for i in range(1000):
            yield ('生产了%s件衣服'%i)            注意这里使用的是yield  返回数据  而不是return  
    j=func()
    print(j.__iter__())
    print(j.__iter__())
    print(j.__iter__())
    import time
    def func():
        with open('file3','r',encoding="utf8") as f3:
            f3.seek(0, 2)#这个位置一定要放在外边因为只有第一次是将光标放在最后,后续就不再操作了,否则
            while True:
                a=f3.read()  #如果放在它上边 while循环中,就会读不到新加的内容
                if not a:    #这里跟最后一个yield   要注意位置和条件
                    time.sleep(0.1)
                    continue
                yield a
    g=func()
    for i in g:
        print(i)
    生成器监听文件,seek的位置,yield需返回的值
    def everage():
        sum=0
        count=0
        average=None
        while True:  #这里一定要写,因为send这种传入后要往下走到下一个yield,所以需要循环
            a=yield average
            sum+=a
            count+=1
            average=sum/count
    g=everage()
    print(g.__next__())#  要先执行这一步,因为用send不能给刚启动的生成器传参数
    print(g.send(12))
    计算移动平均值,用send穿参数,记住在那里才能用send
    
    
  • 相关阅读:
    分享AWS网站
    centos7划分vlan
    在docker容器上如何实现代码的版本管理
    在docker私有仓库如何查看有哪些镜像?
    centos7下报错: import requests ImportError: No module named requests
    Unity2018.4.7导出Xcode工程报错解决方案
    1.OpenGL mac开发环境搭建记录
    unity 模板测试 详解
    游戏战争迷雾
    Unity 移动平台自己编写Shader丢失问题
  • 原文地址:https://www.cnblogs.com/wangkun122/p/7787130.html
Copyright © 2020-2023  润新知