zoukankan      html  css  js  c++  java
  • 迭代器、可迭代对象、迭代器对象

    今天的学习内容有:

            迭代器、可迭代对象、迭代器对象

            for循环内部原理

            生成器和生成器表达式

            面向过程编程

    迭代器

    迭代就是指更新换代的过程,要重复进行,而且每次的迭代都必须基于上一次的结果。

    我们使用for循环的时候就是把元素从容器里一个个取出来,这种过程其实就是迭代。

    迭代器:迭代取值的工具。

    迭代器的作用是提供给你一种不依赖索引取值的方式。

    需要迭代取值的数据类型有:字符串、列表、元组、字典、集合

    可迭代对象

    内置有__iter__方法的都可以叫可迭代对象

    补充:针对双下线开头双下线结尾的方法。推荐读法:双下+方法名。

    基本类型中是可迭代对象的有str、list、tuple、dict、set、文件对象

    文件对象本身就是迭代器对象(所以文件对象执行内置的__iter__之后还是本身,没有任何变化)

    s = 'hello'
    l = [1,2,34,]
    t = (1,2,34)
    s1 = {1,2,3,4}
    d = {'name':'jason'}
    
    res = s.__iter__()
    res1=l.__iter__()
    res2=t.__iter__()
    res3=s1.__iter__()
    res4=d.__iter__()

    可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象。

    迭代器对象

    1.内置有__iter__方法

    2.内置有__next__方法

    补充:迭代器一定是可迭代对象,可迭代对象不一定是迭代器。

    l=[1,2,3,4]
    iter_l=l.__iter__()  # 用__iter__将可迭代对象转换成一个迭代器对象
    print(iter_l.__next__())  # 迭代器取值,调用__next__
    print(iter_l.__next__())  # 调用一次取一个
    print(iter_l.__next__())
    print(iter_l.__next__())
    print(iter_l.__next__())  # 如果取完了直接报错StopIteration

    迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身。

    关于异常处理机制

    d = {'name':'jason','password':'123','hobby':'泡m'}
    iter_d = d.__iter__()  # 将字典变成迭代器对象
    
    while True:
        try:
            print(iter_d.__next__())  # 循环取值
        except StopIteration:  # 异常处理,当出现的异常和你在except后面写的一样时则继续执行下面的代码
            print('取完了'
            break        

    迭代器取值的特点:只能依次向后取,不能后退。

    for循环的内部本质

    d = {'name':'jason','password':'123','hobby':'泡m'}
    for i in d:
        print(i)
    # for 循环后面的in跟的是一个可迭代对象 

    for循环内部的本质:

    1、将in后面的对象调用__iter__转换成迭代器

    2、调用__next__迭代取值

    3、内部有异常捕获StopIteration,当__next__报这个错,自动循环结束

    问:__iter__方法就是用来帮我们生成迭代器对象,而文件对象本身就是迭代器对象,为什么还内置有__iter__方法???

    原因:for循环中跟在in后面的必须可以调用内置的__iter__。所以文本文件是迭代器对象而且内置__iter__,所以迭代器对象无论执行多少次__iter__也还是自己本身。

    #总结
    #可迭代对象:内置有__iter__方法的
    #迭代器对象:既内置有__iter__也内置有__next__方法
    
    #优点:1、不依赖索引取值
    #     2、内存中永远只占一份空间,不会导致内存溢出
    #缺点:1、不能获取指定的元素
    #     2、取完之后会报StopIteration错

    生成器

    本质就是迭代器,是用户自定义的迭代器

    def func():
        print('first')
        yield 666  # yield后面跟的值就是调用迭代器__next__方法你能得到的值
        print('second')
        yield  777,888,999  # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
        yield
    # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
    
    g=func()  # 生成器初始化:将函数变成迭代器
    print(g.__next__())  # 输出为666
    print(g.__next__())  # 输出为(777, 888, 999)
    print(g.__next__())  # 输出为None

    当函数内有yield关键字的时候,调用该函数不会执行函数体代码,而是将函数变成生成器。

    生成器函数:常规函数定义,但是,使用yield语句,而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,是挂起函数的状态,也就是下次可以接着这里执行。

    #yield
    #    1.帮你提供了一种自定义生成器方式
    #    2.会帮你将函数的运行状态暂停住
    #    3.可以返回值
    
    #与return之间异同点
    #      相同点:都可以返回值,并且都可以返回多个
    #      不同点:
    #             yield可以返回多次值,而return只能返回一次函数立即结束
    #             yield还可以接受外部传入的值
    #yield支持外界为其传参
    def dog(name):
        print('%s 准备开吃'%name)
        while True:
            food = yield
            print('%s 吃了 %s'%(name,food))
    g = dog('egon')
    g.__next__()  # 必须先将代码运行至yield 才能够为其传值
    g.send('狗不理包子')  # 给yield左边的变量传参  触发了__next__方法
    g.send('饺子')
    >>>:egon 准备开吃
        egon 吃了 狗不理包子
        egon 吃了 饺子        

    生成器表达式

    res = (i for i in range(1,10) if i != 4)  # 生成器表达式
    print(res)
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    ##把列表解析的[]换成()得到的就是生成器表达式

    不调用__next__方法 生成器内部代码一句都不会运行

    生成器表达式通常用在获取较大容器类型数据的时候

    #自定义range功能
    def my_range(start, end, step=1):
        while start < end:
            yield start
            start += step

    面向过程编程

    面向过程编程:就类似于设计一条流水线
      好处:
        将复杂的问题流程化 从而简单化
      坏处:
        可扩展性较差 一旦需要修改 整体都会受到影响

  • 相关阅读:
    PYthon继承链(egg)的思考和实战
    C++不同类型变量参与运算时的规则
    qt通过QFileDialog获取文件路径&保存文件&选择文件夹
    visual studio 2015调试程序
    C++Primer第五版——书店程序实现
    git rm命令 & git reset和checkout区别
    git diff命令输出解释 & git checkout还原文件到特定版本
    Qt使用connect传参数的两种方式
    QFrame的setFrameStyle函数 && QPalette设置背景
    tr函数作用
  • 原文地址:https://www.cnblogs.com/wangnanfei/p/11190646.html
Copyright © 2011-2022 走看看