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)
  • 相关阅读:
    python爬虫(二)_HTTP的请求和响应
    python迭代器
    矩阵快速幂
    hdu 2256 Problem of Precision
    牛客练习赛17 ABD
    hdu 1575 Tr A
    hdu 1757 矩阵快速幂
    51nod 1402最大值
    51nod 1393 0和1相等串
    勤奋的杨老师
  • 原文地址:https://www.cnblogs.com/scy645670291/p/10873140.html
Copyright © 2011-2022 走看看