zoukankan      html  css  js  c++  java
  • 迭代器与生成器

     1. 迭代器


       

        1. 定义: 内部含有__next__和__iter__ 方法就是迭代器.

        2. 可迭代协议: 可以被for循环的都是可迭代的,内部都有__iter__方法.

        3. 目前所学可迭代对象有: 字符串,列表,字典,元组,集合,range, f = read()

    print(dir(list))   # dir()  : 查看对应的方法,如果有__iter__表示为可迭代对象

        

        4. 可迭代对象.__iter__就可以获得一个迭代器

    result = dir(list)
    iterator = list.__iter__()   # 获得一个迭代器
    print(iterator)

        

        5. 迭代器中的__next__方法可以一个一个的获取值

    list = [1, 2, 3]
    iterator = list.__iter__()
    res = iterator.__next__()
    print(res)
    res = iterator.__next__()
    print(res)

        

        6. for循环的本质: iterator = 可迭代对象.__iter__()

                  iterator.__next__()

    for i in list1.__iter__():
        print(i)

        

        7. 迭代器的好处:

          a. 从容器中取值,会把所有的值都取到

          b. 可以节省内存空间,随着循环每生成一个数,__next__方法每次给出一个数

     2.生成器


       

        1. 生成器的本质: 自己写的迭代器

        2. 生成器函数: 执行后会得到一个生成器作为返回值

          a. 关键字: 只要含有yield关键字的函数都是生成器函数,yield不能和return共用且需要写在函数内部

          b. yield和return的区别: yield和return都能返回后面的值,return执行后结束当前函数,yield也会返回值,但函数不结束

        3. 生成器案例:使用生成器创建十万个娃哈哈,先取50瓶,喝完再取两瓶,喝完再取50瓶

    def wahaha():
    for i in range(100000):
    yield f'第{i}瓶娃哈哈'

    g = wahaha()
    count = 0
    for i in g:
    print(i)
    count += 1
    if count > 50:
    break

    print(g.__next__())
    print(g.__next__())
    for i in g:
    print(i)
    count += 1
    if count > 100:
    break

        

        4. 生成器函数的特点:

          a. 调用函数之后函数不执行,返回一个生成器

          b. 每次调用__next__方法的时候会取到一个值,直到取完最后一个,再执行next的时候会报错

        5. 从生成器中取值的方法:

          a. __next__方法

          b. for 循环

          c. 数据类型强制转换,占用内存

        6. send()方法 : 获取下一个值的效果和next基本一致

          a. 特点 : 只是在获取下一个值的时候,给上一个yield的地方传递一个数据

          b. 注意事项 : 第一次使用生成器的时候,使用next获取下一个值

                最后一个yield不能接收外部的值

    def generator():
        print(123)
        content = yield 1
        print('=========', content)
        print(456)
        yield 2
    
    g = generator()
    print(g)
    result = g.__next__()
    print(result)
    result = g.send('hello')
    print(result)

        

        7. send案例 : 计算移动平均值

    def avgerage():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg
            sum += num
            count += 1
            avg = sum/count
    
    avg_g = avgerage()
    avg_g.__next__()   # 激活生成器
    result = avg_g.send(10)
    result = avg_g.send(20)
    result = avg_g.send(30)
    result = avg_g.send(40)
    print(result)

        

        8. 生成器结合装饰器: 预激生成器的装饰器

    def init(func):
        def inner(*args, **kwargs):
            g = func(*args, **kwargs)
            g.__next__()    # 在装饰器内部激活
            return g
        return inner
    
    @init
    def avgerage():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg
            sum += num
            count += 1
            avg = sum/count
    
    avg_g = avgerage()
    result = avg_g.send(10)
    result = avg_g.send(20)
    result = avg_g.send(30)
    result = avg_g.send(40)
    print(result)

        

        9. yield from 将容器内的数据挨个遍历

    def generator():
        a = '12345'
        b = 'abcde'
        yield from a
        yield from b
    
    g = generator()
    for i in g:
        print(i)

        10. 生成器表达式

    generator = (i ** 2 for i in range(10))
    print(generator)
    for i in generator:
        print(i)
  • 相关阅读:
    使用Random类生成指定范围的随机数
    js ==和===的区别
    js中的undefined
    js的split函数
    springboot发送邮件
    1032 Sharing (25分)(数组链表)
    1031 Hello World for U (20分)
    1030 Travel Plan (30分)(dijkstra 具有多种决定因素)
    1029 Median (25分)
    1026 Table Tennis (30分)
  • 原文地址:https://www.cnblogs.com/scy645670291/p/10873140.html
Copyright © 2011-2022 走看看