python--迭代器與生成器

一、生成器

1. 列表生成

>>> [i*2 for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


列表生產優點:節約內存,採取邊生成邊使用元素的模式,使用完了則銷燬。而普通的列表,是一次性在內存中創建。


2. 創建第一個生成器 generator

>>> gen = (i*2 for i in range(10))   # 即把列表的[] 改成()
>>> for j in gen:
...   print(j)
...
0
2
4
6
8
10
12
14
16
18


3. next使用(__next__)

>>> gen = (i*2 for i in range(10))
>>> gen.__next__()
0
>>> gen.__next__()
2
>>> gen.__next__()
4
>>> next(gen)
6

注:如果取完了,則會報錯

>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration


4. for循環迭代

>>> gen = (i*2 for i in range(10))
>>> for i in gen:
...   print(i)
...
0
2
4
6
8
10
12
14
16
18


5. 生成器保存的是算法,通過算法計算式出下一個值,__next__()

案例:

def fib(max):
    count, a, b = 0, 0, 1    #1
    while count < max:       #2
        yield b            #3
        a, b = b, a+b      #4
        
        count = count+1    #5
g = fib(6)
print(g)    # 結果:<generator object fib at 0x0000000000731DB0>
for i in g:
    print(i)

結果:

1    #1-->2-->3    count=0
1    #4-->5--2-->3 count=1
2    #4-->5--2-->3 count=2
3    #4-->5--2-->3 count=3
5    #4-->5--2-->3 count=4
8    #4-->5--2-->3 count=5

使用while循環:

def fib(max):
    count, a, b = 0, 0, 1
    while count < max:
        yield b
        a, b = b, a+b
        count = count+1
g = fib(6)
print(g)
while True:
    try:
        print('value:', g.__next__())
    except StopIteration as e:
        print('except value:', e.value)
        break

結果:

<generator object fib at 0x0000000001F71DB0>
value: 1
value: 1
value: 2
value: 3
value: 5
value: 8
except value: None


6. 通過yield 實現併發

import time
def consumer(name):
    print('%s開始吃水果' % name)
    while True:
        fruit = yield
        print('%s吃了%s水果' % (name, fruit))
def productor():
    Sam = consumer('Sam')
    Jey = consumer('Jey')
    Sam.__next__()   # 是爲了讓程序走到fruit = yield,準備吃的步驟
    Jey.__next__()
    for i in range(1,4):
        time.sleep(1)
        print('開始分發水果.....')
        Sam.send(i)
        Jey.send(i)
productor()

結果:

Sam開始吃水果
Jey開始吃水果
開始分發水果.....
Sam吃了1水果
Jey吃了1水果
開始分發水果.....
Sam吃了2水果
Jey吃了2水果
開始分發水果.....
Sam吃了3水果
Jey吃了3水果


二、迭代器

1. 可迭代對象  Iterable

----> 字符串、列表、元組、字典、集合   # 不是生成器

----> 生成器,包括帶yield的函數

使用isinstance判斷是否可迭代對象;

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance('ggg', Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance((i for i in range(3)), Iterable)
True


2. 迭代器的定義

可以被next()調用並不斷返回下一個值,成爲迭代器:Iterator

>>> from collections import Iterator
>>> isinstance([], Iterator)
False
>>> isinstance((i for i in range(3)), Iterator)
True


3. 使用iter() 把iterable 變成iterator

>>> from collections import Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('asd'), Iterator)
True


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章