Python_迭代器、生成器

迭代器和生成器

迭代器:

  只要是能被 for 循環的數據類型,就必定擁有 __iter__ 方法函數

  一個列表執行了 __iter__() 以後的返回值就是一個迭代器spa

print([].__iter__())

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

  經過 next 就能夠從迭代器中一個一個的取值對象

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

1
2

可迭代協議:  

  只要含有 __iter__ 方法的都是可迭代的(__iter__ 與 iter() 效果是同樣的)blog

迭代器協議:

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

for 循環:generator

  只有是可迭代對象的時候才能用forit

  當咱們遇到一個新的變量,不肯定能不能 for 循環的時候,就判斷它是否可迭代class

迭代器的好處:

  從容器類型中一個一個的取值,黑吧全部的值都取到。容器

  節省內存空間

    迭代器並不會在內存中再佔用一塊內存

    每次 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

  一、send 獲取下一個值的效果和 next 基本一致

  二、只是在獲取下一個值的時候,給上一個 yield 的位置傳遞一個數據

  三、使用 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)
相關文章
相關標籤/搜索