• 函数之迭代器生成器


    一.迭代器

    1.什么是迭代器?

    迭代取值的工具

    2.为什么要用迭代器?

    在不利用for循环取值的情况下,我们分别对 字符串,列表,字典,元组,集合进行取值。我们发现字典和集合无法取值,因为他们俩都是无序的,不能利用索引取值,所以这时候我们就用到了迭代器。

    迭代器给我们提供了一种不依赖索引取值的方式

    3.如何用迭代器?

    首先引入一个可迭代对象概念

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

    __iter__  读作  双下+方法名

    在基本数据类型中可迭代对象有:str  list     tuple  dict  set  文件对象

    之后我们就可以再介绍迭代器对象

    1.内置有__iter__方法

    2.内置有__next__方法

    ps:迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象

    #生成一个迭代器对象
    l = [1,2,3,4]
    iter_l = l.__iter__()
    #迭代器取值 调用__next__
    print(iter_l.__next__())
    print(iter_l.__next__())
    print(iter_l.__next__())
    print(iter_l.__next__())
    print(iter_l.__next__())  #如果取完了,就会报错
    f1 = open('xxx.txt','r',encoding = 'utf-8')
    #调用f1 内置的__iter__方法
    iter_f =f1.__iter__()
    print(iter_f is f1)
    #True

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

    上面有个问题,如果取多了里面没有值了的话,就会报错

    下面我们进行异常处理

    while True:
        try:
            print(iter_d.__next__())
        except StopIteration:
            break

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

    for循环的本质

    for循环内部的本质

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

      2.调用__next__迭代取值

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

    下面总结一下迭代器:

    可迭代对象:内置有__iter__方法的
    迭代器对象:既内置有__iter__也内置有__next__方法

    迭代取值:
        优点
          1.不依赖于索引取值
          2.内存中永远只占一份空间,不会导致内存溢出

        缺点
          1.不能够获取指定的元素
          2.取完之后会报StopIteration错

    二.生成器

    1.什么是生成器?

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

    def func():
        print('first)
        yield 666
        print('second')
        yield 777
        pirnt('third')
        yield 888
        print('forth')
        yield
    # yield后面跟的值就是调用迭代器__next__方法你能得到的值
    # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
    g = func()
    print(g)
    print(g.__next__)
    print(g.__next__)
    print(g.__next__)
    print(g.__next__)
    print(g.__next__)

    例子: 

    for i in range(1,10,2):
        print(i)

    将上面的写成一个生成器

    def my_range(start,end,step=1)
        while start<end:
            yield start
            start+=step
    
    for j in my_range(1,10,2)
            print(j)

    yield 表达式形式

    yield支持外界为其传参

    def dog(name):
      print('%s 准备开吃'%name)
          while  True:
                food = yield
                print('%s吃了%s' %(name,food))

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

    g = dog('egon')

    g.__next__()   必须先将代码运行至yield 才能够为其传值

    g.send('包子')  给yield左边的变量传参  同时出发__next__()方法

    yield
    1.帮你提供了一种自定义生成器方式
    2.会帮你将函数的运行状态暂停住
    3.可以返回值

    与return之间异同点
    相同点:都可以返回值,并且都可以返回多个
    不同点:
    yield可以返回多次值,而return只能返回一次函数立即结束
    yield还可以接受外部传入的值

    生成器表达式

    res = (i for i in range(1,100000000) if i != 4)
    print(res)

    生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行(*********)

    面向过程编程

    面向过程编程:就类似于设计一条流水线

      好处:将复杂的问题流程化 从而简单化

      坏处:可扩展性较差  一但需要修改,整体都会受到影响

    万般皆下品,唯有读书高!
  • 相关阅读:
    c++ primer 中讲的顶层const 和 底层 const 理解
    github 0 学习
    MySQL 0 学习
    c++11 move构造函数和move operator 函数 学习
    c++11 多线程 1
    c++ 多线程 0
    学习 emplace_back() 和 push_back 的区别 emplace_back效率高
    crontab执行脚本失败问题
    lucene 排序
    maven 内置变量
  • 原文地址:https://www.cnblogs.com/s686zhou/p/11189724.html
Copyright © 2020-2023  润新知