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

    迭代器和生成器

    迭代器:

      只要是能被 for 循环的数据类型,就一定拥有 __iter__ 方法

      一个列表执行了 __iter__() 之后的返回值就是一个迭代器

    print([].__iter__())

      只要含有 __iter__ 方法的都是可迭代的。

      通过 next 就可以从迭代器中一个一个的取值

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

    可迭代协议:  

      只要含有 __iter__ 方法的都是可迭代的(__iter__ 与 iter() 效果是一样的)

    迭代器协议:

      内部含有 __next__ 和 __iter__ 方法的就是迭代器

    for 循环:

      只有是可迭代对象的时候才能用for

      当我们遇到一个新的变量,不确定能不能 for 循环的时候,就判断它是否可迭代

    迭代器的好处:

      从容器类型中一个一个的取值,黑吧所有的值都取到。

      节省内存空间

        迭代器并不会在内存中再占用一块内存

        每次 next 每次给一个值

    l = [1, 2, 3, 4, 5]
    iterator = l.__iter__()
    while True:
        print(iterator.__next__())

    生成器

    生成器函数:

      本质上就是我们自己写的函数

      只要含有 yield 关键字的函数都是生成器函数

      yield 不能和 return 共用且需要写在函数内

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

    def generator():
        print(1)
        yield 'a'
    ret = generator()
    print(ret)
    print(ret.__next__())

    <generator object generator at 0x0000000000A03AF0>
    1
    a

    send

      1、send 获取下一个值的效果和 next 基本一致

      2、只是在获取下一个值的时候,给上一个 yield 的位置传递一个数据

      3、使用 send 的注意事项

        第一次使用生成器的时候,是用 next 获取下一个值

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

    def generator():
        print(123)
        content = yield 1
        print('=======',content)
        print(456)
        yield2
    
    g = generator()
    ret = g.__next__()
    print('***',ret)
    ret = g.send('hello')   #send的效果和next一样
    print('***',ret)

    预激生成器的装饰器

    def init(func):   #装饰器
        def inner(*args,**kwargs):
            g = func(*args,**kwargs)    #g = average()
            g.__next__()
            return g
        return inner
    
    @init
    def average():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg
            sum += num    # 10
            count += 1    # 1
            avg = sum/count
    
    avg_g = average()   #===> inner
    ret = avg_g.send(10)
    print(ret)
    ret = avg_g.send(20)
    print(ret)
  • 相关阅读:
    高阶函数
    如何理解data URL?
    JS对象的创建方式
    数组中的map方法
    奇怪的 Javascript
    什么场景不适合箭头函数
    协方差矩阵学习[转载]
    PAT 1140 Look-and-say Sequence [比较]
    PAT 1089 Insert or Merge[难]
    PAT 1096 Consecutive Factors[难]
  • 原文地址:https://www.cnblogs.com/Chong-Yang/p/8178865.html
Copyright © 2011-2022 走看看