一、生成器
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