• python 迭代器协议和生成器


    一、什么是迭代器协议

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

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

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

    二、python中强大的for循环机制

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

    正文清源:

    很多人会想,for循环的本质就是遵循迭代器协议去访问对象,那么for循环的对象肯定都是迭代器了啊。没错,那既然这样,for循环可以遍历(字符串,列表,元祖,字典,集合,文件对象),那这些类型的数据肯定是可迭代对象啊?但是,我tmd为什么定义一个列表=[1, 2, 3, 4]没有next方法,打脸麽?

    (字符串,列表,元祖,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象。

    然后for循环调用可迭代对象的__next__方法取值,而且for循环会捕捉stoplteration异常,以终止迭代。

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 ls = ['a', 'b', 'c']
     4 # 一、下标访问方式,默认从0开始计数
     5 print(ls[0])
     6 print(ls[1])
     7 print(ls[2])
     8 # print(ls[3]) # 报错,超出索引下标
     9 # # 二、遵循迭代器协议访问方式
    10 diedai_ls = ls.__iter__()
    11 print(diedai_ls.__next__())
    12 print(diedai_ls.__next__())
    13 print(diedai_ls.__next__())
    14 # 三for循环访问方式
    15 for item in ls:
    16     print(item)
    17 # 使用while循环方式
    18 diedai_ls = ls.__iter__()
    19 while True:
    20     try:
    21         print(diedai_ls.__next__())
    22     except StopIteration:
    23         print('迭代完啦!')
    24         break

     三、生成器初探

    什么是生成器?

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

    生成器分类及在Python中的变现形式:(Python有两种不同的方式提供生成器)

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

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 def test():
     4     yield 1  # 1
     5     yield 2  # 2
     6     yield 3  # 3
     7 
     8 
     9 res = test()
    10 print(res.__next__())
    11 print(res.__next__())
    12 print(res.__next__())
    13 # print(res.__next__())  # 报错,超出索引下标

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

    1 #!/usr/bin/env python
    2 # -*- coding:utf-8 -*-
    3 ls = ('数字:%s' % i for i in range(10))
    4 print(ls.__next__())  # 数字:0
    5 print(ls.__next__())  # 数字:1
    6 print(ls.__next__())  # 数字:3

    为何使用生成器之生成器的特点

    Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生产层器的主要好处。

    生成器小结:

    a.是可迭代对象

    b.实现了延迟计算,省内存

    c.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处,记住哦~~

    四、生成器表达式与三元运算

    1 #!/usr/bin/env python
    2 # -*- coding:utf-8 -*-
    3 name = 'alex'
    4 res = 'True' if name == 'alex' else 'False'
    5 print(res)

     五、列表解析

    1 ls = ['数字:%s' % i for i in range(10)]
    2 print(ls)

     总结:

    1.把列表解析的[]换成()得到的就是生成器表达式

    2.列表解析与生成器表达式都是一种遍历的编程方式,只不过生成器表达式更节省内存

    3.Python不但使用迭代器协议让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如,sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和:

    1 print(sum(x for x in range(1000000000000000)))
    作者:陈彦斌

    个性签名:没有学不会的技术,只有不学习的人!
    联系方式:543210188(WeChat/QQ),推荐WeChat
  • 相关阅读:
    [zjoi2012]灾难——拓扑排序+灭绝树
    [bzoj3590]Quare——状压DP
    [bzoj4144]Petrol——最小生成树+最短路
    [bzoj2407]探险——重构图+最短路
    [bzoj2725]故乡的梦——最短路+线段树
    [bzoj2118]墨墨的等式——同余最短路
    [loj2736][JOISC 2016 Day3]回转寿司——分块+堆
    PHP学习笔记二十四【Get Set】
    PHP学习笔记二十三【This】
    PHP学习笔记二十二【静态方法二】
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/10294814.html
Copyright © 2020-2023  润新知