• 迭代器和生成器


    迭代器和生成器

    1.iterable 可迭代:

        可迭代的数据类型:列表、字符串、集合、字典 、元祖 

    • 迭代器我们可以理解为一个容器。我们从这个容器中一个接一个把值取出来,这个过程就是迭代过程
    • '__iter__'   内部含有'__iter__'方法的数据类型就是可迭代的

    2.iterator迭代器:

        迭代器我们可以理解为一个容器。我们从这个容器中一个接一个把值取出来,这个过程就是迭代过程

    迭代器的用法
    • Python中一切皆对象,可迭代的等于可迭代对象
    • 可迭代的 必须含有'__iter__' 的方法 #可迭代协议
    • 迭代器比可迭代多一个'__next__'方法
    • 迭代器:包含'__next__'和'__iter__'的方法就是迭代器 #这个是迭代器协议
    • 包含'__next__'的可迭代对象就是迭代器。
    • 迭代器是可迭代的 的一部分

    迭代器的调用

    • for循环是让我们更简单的使用迭代器
    • 用迭代器取值就不需要关心索引或者key的问题了
    • 迭代器是个好东西
    • 目前我们已知的可迭代的都是python提供给我们的
    • range()
    • f
    • enumerate()
    • 但是在平时我们写代码的过程中我们用for循环就足够了
    如何判断一个变量是迭代器  或者  是可迭代的
    l = [1,2,3,4]
    l_iter = l.__iter__()
    print('__iter__' in dir(l))
    print('__next__' in dir(l_iter))
    
    # 运行结果:
    
    True
    True

     isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

    #引入可迭代
    from collections.abc import Iterable
    print(isinstance([1,2,3,4],Iterable))
    
     #引入迭代器
    from collections.abc import Iterator
    print(isinstance([1,2,3,4],Iterator))
    
    #运行结果:
    True
    False
    

     

    3.生成器

      生成器是一次生成一个值的特殊类型函数。可以将其视为可恢复函数。# 调用该函数将返回一个可用于生成连续 x 值的生成【Generator】,简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候又从上次中断的地方开始执行,而生成器内的所有变量参数都会被保存下来供下一次使用。

     自己写的可迭代的就是生成器     生成器的本质是可迭代的生成器所以优点跟迭代器一样   不同点:生成器是自己写Python代码

    生成器的实现是由两种方式:
      第一种:生成器函数
    #generator   生成器   迭代器的一种
    def g_func():
        print('qwer')
        yield 1
        yield 2             #返回   但没终止
    
    g = g_func()
    print(g)
    print(g.__next__())
    print(g.__next__())

    #生成器函数与普通函数区别:
    #1.生成器函数中含有yield关键字
    #2.生成器函数调用的时候不会立即执行,而是返回一个生成器
    #第二种:生成器表达式
    def gen():
        for i in range(4):
            yield i
    base = gen()
    for n in (2,10):
        base = (i+n for i in base)
    print(list(base))
    
    
    [21,22,23,24]
    
    #简单解答:
    因为for循环了两次,并对base从新赋值了,所以可以简化为(i+n for i in (i+n for i in base))  而n 全部引用了后赋值的10。最里面的base引用的是gen。
    

      

    列表推导式:

    x = [i**2 for i in y]
    print(x)
    [1, 4, 9, 16, 25, 36, 49, 64]  

    求偶及取余:
    # l = [声明量   遍历范围   条件判断 ]
    
    l = [i for i in range(10) if i % 2 == 0 ]
    
    print(l)
    
    [0, 2, 4, 6, 8] 
    #区分大小写
    mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
    mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase}
    print(mcase_frequency)
    # 字典推导式
    dic = {'a':10,'b':20}
    dic_t = {dic[k]:k for k in dic}
    print(dic_t)
    

     

    • 生成器函数 是生成一个生成器的函数 生成器的本质是迭代器
    • 特点:带有yeild关键字,调用后函数内代码不执行
    • 触发的方式:next 、 send 、 for循环
    • next 和 send 执行几次 拿几次数据 取完报错
    • for循环每次取一个 去玩为止 不会报错
    • send(空)相当于 next
    • send是在next的基础上传一个值到生成器函数内
    • send不能用在生成器操作的第一次
    def average():
        total = 0.0
        count = 0
        average = None
        while True:
            term = yield average
            total += term
            count += 1
            average = total/count
    
    g_avg = average()
    print(g_avg.__next__())
    print(g_avg.send(10))
    print(g_avg.send(20))
    

      

     

     
     
    
    

     

     

     
  • 相关阅读:
    python的is和==
    pycharm设置
    springboot 配置中心 nacos 简易部署+ 手把手教 涂涂
    解决: springboot 有了eurake怎么再添加 nacos? 【springboot配置多注册中心,同时生效~,不是切换】 涂涂
    .NET Core/.NET5/.NET6 开源项目汇总5:(权限)管理系统项目
    解决ueditor报错:ZeroClipboard undefined
    如何评价 Qt 的发展前景?
    WPF HandyControl开源UI库学习笔记
    C#中的深度学习(一):使用OpenCV识别硬币
    使用SVN进行文档管理和部门知识库建设的建议
  • 原文地址:https://www.cnblogs.com/mainstream/p/11041088.html
Copyright © 2020-2023  润新知