Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 254|回复: 0

[默认分类] Python入门之迭代器/生成器/yield的表达方式/面向过程编程

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-4-2 11:34:14 | 显示全部楼层 |阅读模式
    本章内容
        迭代器
        面向过程编程
          一、什么是迭代
          二、什么是迭代器
          三、迭代器演示和举例
          四、生成器yield基础
          五、生成器yield的表达式形式
          六、面向过程编程
    ============================================================
      
    一、什么是迭代
      
      迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

    1. # 我们以前学习的while按照如下执行,会一直执行下去;
    2. # 但是,while只是一个开关作用,while在这里并没有体现出迭代的精髓"每一次迭代得到的结果会作为下一次迭代的初始值"
    3. while True:
    4.     print("Hello World!")
    复制代码



    1. # 下面我们遍历列表,其中每一次的n都是基于上一次的n,依次遍历
    2. # 这里就体现了迭代的精髓“每一次的迭代的结果编程下一次迭代的初始值”
    3. l = ["a", "b", "c"]
    4. n = 0
    5. while n < len(l):
    6.     print(l(n))
    7.     n += 1
    复制代码


      
    二、什么是迭代器
      
      要想了解迭代器到底是什么,必须了解一个概念,即什么是可迭代对象。
    python中,可迭代对象都内置有_iter_方法,拥有_iter_方法的对象,就是可迭代对象。

    1. # 以下都是可迭代对象(字符串,列表,元组,字典,集合,文件)
    2. str = "hello"
    3. list1 = [1, 2, 3]
    4. tup1 = (4,5,6)
    5. dic = {"x": 1}
    6. s1 = {"a", "b", "c"}
    7. f = open("a.txt", "w", encoding="utf-8")
    8. # 需要注意文件由于本身过大的特性,必须被定义为可迭代对象,不然很容易内存溢出
    复制代码


      
    三、迭代器对象
      
      1. 什么是迭代器对象
      
      迭代器,就是迭代取值的工具。可迭代的对象,执行._iter_()方法得到的返回值就是迭代器对象。我们以前学过的字符串,列表,元组,字典,集合都是可迭代对象,执行内置的._iter_()方法得到对应的迭代器对象,根据部分对象的特征,我们可以根据索引取出特定的值,但是我们取值受限于索引,依赖什么就受限于什么。
      
      在Python中,我们要进行迭代处理的对象很多,但是它们并没有上面对象的特点。先天的不足,只能通过别的方法实现,这里我们可以通过迭代器对象,使用迭代器对象的._next_()方法,逐一取出,避免这种限制。
      
      迭代器,就是我们自己把对应的对象处理,处理成带有迭代性质的对象。
      

    1. # 集合
    2. s1 = {"a", "b", "c"}
    3. # 可迭代对象s1集合,执行内置的._iter_()方法,获得迭代器对象,然后就可以逐一取出来
    4. iter_s1 = s1._iter_()
    5. print(iter_s1._next_())
    6. print(iter_s1._next_())
    7. print(iter_s1._next_())
    复制代码


      

    1. # 字典
    2. dic1 = {"x":1, "y":2, "z":3}
    3. # 可迭代对象dic1字典,执行内置的._iter_()方法,获得迭代器对象,然后就可以逐一取出来
    4. iter_dic1 = dic1._iter_()
    5. print(iter_dic1._next_())
    6. print(iter_dic1._next_())
    7. print(iter_dic1._next_())
    复制代码



    1. # 列表
    2. L1 = [2,3,4,]
    3. # 可迭代对象L1列表,执行内置的._iter_()方法,获得迭代器对象,然后可以逐一取出来
    4. iter_L1 = L1._iter_()
    5. print(iter_L1._next_())
    6. print(iter_L1._next_())
    7. print(iter_L1._next_())
    复制代码



    1. # 字符串
    2. str1 = "hello"
    3. #  可迭代对象str1字符串,执行内置的._iter_()方法,获得迭代器对象,然后逐一取出
    4. iter_str1 = iter_str1._iter_()
    5. print(iter_str1._next_())
    6. print(iter_str1._next_())
    7. print(iter_str1._next_())
    8. print(iter_str1._next_())
    9. print(iter_str1._next_())
    复制代码



    1. # 我们在遍历字符串的时候,发现会报错,那就引入抛出异常机制
    复制代码




    1. # 文件
    2. f1 = open("a.txt", "r", encoding = "utf-8")
    3. # 可迭代对象f1文件,执行内置的._iter_()方法,获取迭代器对象,然后逐一取出
    4. iter_f1 = f1._iter_()
    5. while True:
    6.     try:
    7.         print(iter_f1._next_())
    8.     except StopIteration:
    9.         break
    复制代码



    1. # 迭代文件的时候,你会发现打印出来,有空行,因为在文件中换行是由‘\n’代表的
    复制代码



      
    1.   2. 迭代器之for循环的应用  
    2.   for循环,是一种迭代器循环,因为for要调用可迭代对象内置的._iter_()方法,而且关键字in之后必须跟可迭代对象或者迭代器。
    复制代码


    1. #基于for循环,我们可以完全不再依赖索引去取值了
    2. dic={"a":1,"b":2,"c":3}
    3. for k in dic:
    4.     print(dic[k])
    5. # for循环的工作原理
    6. #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
    7. #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    8. #3: 重复过程2,直到捕捉到异常StopIteration,结束循环
    复制代码


      
      3. 迭代器的优点
      
        1. 提供了一种可以不依赖索引的取值方式
        2. 在内存中只生成一个迭代器对象,每次产生一个值,不用把对象完整的加载到内存,更加节省内存

    1. # 下图中,iter_l的内存信息,你会看到内存中标记的是ist_iterator对象
    复制代码


    1.   4. 迭代器的缺点
    2.     1. 只能用_next_()方法,一个一个取出来,取值效率低
    3.     2. 取值方向只能往后取,而且是一次性使用,无法往复取值
    4. [img]http://www.itdaan.com/imgs/7/1/4/5/49/cd158191d83b9bb8ef8a53db13e35097.jpe[/img]
    复制代码

      
      5. 可迭代对象  VS 迭代器对象
      


    1. # 补充说明, 文件有时候本身较大,一次全部加载到内存,费事费力,所以要被定义为一个迭代器对象,每次取一点,节省内存,提升效率
    复制代码


      
    四、生成器yield基础
      
      1. 生成器本身就是迭代器,相当于我们借助函数,自己制造了一个迭代器。
               生成器的用法其实就是迭代器的用法。
      
         yield的用法(面向任何可迭代对象):
         函数内包含yield关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象。

    1. # 注意下图中,内存的标记为生成器generator
    复制代码




    1. # 生成器的本质就是迭代器,下面res._iter_() 就是 res本身
    复制代码




      
      2. yeild的过程
      

      
      3. yield的功能
      
        1. yield与return类似,都可以返回值,不同之处在于,yield可以返回多个值而且可以暂停,在暂停的基础上再次执行;return就不一样了,代表函数的结束。
          2. yield可以让已经封装好的函数能够使用_iter_和_next_方法

          3. yield遵循迭代器的取值方式,函数的触发执行和函数的保存都是通过yeild保存。

    1. def  start():
    2.     print("Starting.......")
    3.     while True:
    4.         x = yield       #此处是yield的表达式形式
    5.         print(x)
    6. f = start()
    7. next(f)         #next(g) == g.send(None)
    8. """
    9. send的效果:
    10. 1. 将携带的值传给yield,不是x,然后yield在复制给x
    11. 2. send()方法具有和next()方法一样的功能,能在传值的基础上继续执行,直到再次碰到
    12.     yield结束
    13. """
    14. g.send(2)     
    复制代码


        yield表达式形式,例如 x = yield, 生成器会有一个send操作
        send的效果:
          1. 先从为暂停位置的那个yiled传一个值,然后yield会把值,赋值给x
          2. 与next的功能一样
          3. send 传多个值时, 必须以元组的形式,保持有序,不能修改

    1. def  start():
    2.     print("Starting.......")
    3.     while True:
    4.         x = yield       #此处是yield的表达式形式
    5.         print(x)
    6. start()
    7. start() # 到这里就不会运行print("Starting......."),因为再次调用函数,解释器在检测语法
    8.               的时候,检测到有yield,那么在执行该函数的时候就不会运行
    复制代码



    1. # 结合上面,下面实例是可变长度参数的应用实例
    复制代码



    1. def foo(func):
    2.     def foo1(*args, **kwargs):
    3.         g = func(*args, **kwargs)
    4.         next(g)
    5.         return g
    6.     return foo1
    7. @foo
    8. def eater(name):
    9.     print("%s starts to ear" % name)
    10.     foo_list = []
    11.     while True:
    12.         food = yield food_list
    13.         food_list.append(food)
    14.         print("%s starts to eat %s" % (name, food))
    15.         print(food_list)
    16. m = eater("Alex")
    17. m.send("Bread")
    18.         
    复制代码




    1. #  结合上面理论,理解以下yield表达式的范例
    复制代码


      


      
      4. yield总结
        
        1. 为我们提供了一种自定义迭代器的方式,可以在函数内用yield关键字;调用函数拿到的结果就是生成器,可以利用生成器的迭代器方法
        2. yield可以像return一样用于返回值;return一次只能返回一次,而且代表函数结束,yield可以返回多次值

        3. yield可以保存函数的执行状态


      
    六、 面向过程编程
      
      1. 什么是面向过程编程
          这个概念的核心对象是‘过程’,解决问题的过程,即先做什么,后做什么
      
      2. 基于面向过程编写程序,就像设计一条流水线,类似机械的思维方式
      
      3. 优点和缺点
        
        优点:复杂问题流程化,进而简单化
        缺点:可扩展性差,修改流水线的任意一个部分,都会牵一发而动全身
        应用:固定场景,扩展性要求不高,典型案例如linux内核,git,httpd等等
      
      4. 实例:
        
        流水线1:
          用户输入用户名、密码  ===》 用户验证 ===》 欢迎界面
      
        流水线2:
          用户发起sql请求 ===》sql解析 ===》执行功能
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-3-28 22:18 , Processed in 0.344489 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表