• 迭代器与生成器


    一、迭代器

    1、什么是迭代器协议

    1、迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stopiteration异常,以终止迭代。(只能往后走不能往前退)

    2、可迭代对象:实现了迭代器协议的对象。(如何实现:对象内部定义了一个__iter__()方法)

    3、协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

    2、迭代器与可迭代对象

    1、迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器。

    2、可迭代对象:可以直接作用于for循环的对象。

    3、for循环

    for循环的本质:循环所有的对象,全部都是使用迭代器协议。

    for循环的实现:

    L = [1,2,3,4,5]
    L = L.__iter__()    #使用内部方法__iter__()将其变为可迭代对象
    print(L.__next__())    #使用可迭代对象提供的方法__next__()循环取值        
    print(L.__next__())
    print(L.__next__())
    print(L.__next__())
    print(L.__next__())    
    View Code

    可迭代对象会抛出StopIteration,为了解决这一问题,加入异常处理,模拟真实的for循环机制

    L = [1,2,3,4,5]
    L = L.__iter__()
    try:
        while True:
            print(L.__next__())
    except StopIteration:
        pass
    View Code

    4、for循环的重要性

    例如:list对象

    L = [1,2,3,4,5]
    index = 0
    while index < len(L):
        print(L[index])
        index += 1
    View Code

    象list这样的数据,都是有下标的,也就是可以通过索引获取值,但是想dict,set这样的数据就不行。

    所有通过for可以实现所有的可迭代对象,也就是for提供了一个可迭代对象的通用方法。

    二、生成器

    1、什么使生成器

    可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他数据类型需要调用自己内置的__iter__()方法),所有生成器就是可迭代对象。

    2、生成器分类

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

    2、生成器表达式:类似列表推导,但是,生成器返回的是一个生成器对象

    3、生成器表达式与列表解析

    1、三元表达式

    name = "lilon"
    L = "True" if name == "lilong"  else "lizhi"
    print(L)

    2、列表生成式

    L = [i for i in range(10)]
    print(L)

    3、生成器表达式(注意括号的区别以及返回值)

    L = (i for i in range(10))
    print(L)
    print(L.__next__())

    4、生成器表达式的运用

    利用sum()函数计算和

    1、列表式:

    x = sum( [i for i in range(10)] )
    print(x)

    2、生成器式:(省略了一个括号)

    x = sum( i for i in range(10) )
    print(x)

     4、生成器函数

    def test():
        print("返回0")
        yield 0
        print("返回1")
        yield 1
        print("返回2")
        yield 2
    
    v = test()
    print(v)
    print(v.__next__())
    print(v.__next__())
    print(v.__next__())

    遇见一个yield,函数会保存状态,以便下次从yield开始执行。

  • 相关阅读:
    C++ 顺序表实现
    C++ 第三十四天
    C++ 第三十三天
    机器学习相关- 学习资料收集
    【Debian 8.8】Java 8 安装以及环境变量配置
    算法导论(第三版)练习 1.2-1 ~ 1.1-3
    条款33: 明智地使用内联
    条款32: 尽可能地推迟变量的定义
    条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
    【Nginx】进程模型
  • 原文地址:https://www.cnblogs.com/lilong74/p/11333920.html
Copyright © 2020-2023  润新知