在python中,一邊迴圈一邊計算的機制,稱為生成器:generator。
列表所有資料都在記憶體中,如果有海量資料的話將會非常耗記憶體。
如:僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。
如果列表元素按照某種演算法推算出來,那我們就可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間。
簡單一句話:我又想要得到龐大的資料,又想讓它占用空間少,那就用生成器!
第一種方法很簡單,只要把乙個列表生成式的改成
()
,就建立了乙個generator:
>>> l = [x * x for x in range(10)]建立>>> l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
at 0x1022ef630>
l
和g
的區別僅在於最外層的
和()
,l
是乙個list,而g
是乙個generator。
方法二, 如果乙個函式中包含yield
關鍵字,那麼這個函式就不再是乙個普通函式,而是乙個generator。呼叫函式就是建立了乙個生成器(generator)物件。
(1)生成器(generator)能夠迭代的關鍵是它有乙個next()方法,
工作原理就是通過重複呼叫next()方法,直到捕獲乙個異常。
(2)帶有 yield 的函式不再是乙個普通函式,而是乙個生成器generator。
可用next()呼叫生成器物件來取值。next 兩種方式 t.__next__() | next(t)。
可用for 迴圈獲取返回值(每執行一次,取生成器裡面乙個值)
(基本上不會用next()
來獲取下乙個返回值,而是直接使用for
迴圈來迭代)。
(3)yield相當於 return 返回乙個值,並且記住這個返回的位置,下次迭代時,**從yield的下一條語句開始執行。
(4).send() 和next()一樣,都能讓生成器繼續往下走一步(下次遇到yield停),但send()能傳乙個值,這個值作為yield表示式整體的結果
——換句話說,就是send可以強行修改上乙個yield表示式值。比如函式中有乙個yield賦值,a = yield 5,第一次迭代到這裡會返回5,a還沒有賦值。第二次迭代時,使用.send(10),那麼,就是強行修改yield 5表示式的值為10,本來是5的,那麼a=10
感受下yield返回值的過程(關注點:每次停在哪,下次又開始在哪)及send()傳參的通訊過程,
思考none是如何產生的(第一次取值:yield 返回了 i 值 0,停在yield i,temp沒賦到值。第二次取值,開始在print,temp沒被賦值,故列印none,i加1,繼續while判斷,yield 返回了 i 值 1,停在yield i):
好了,話不多說,翠花,上栗子:
1 #encoding:utf-8結果:2 def yield_test(n):
3 for i in range(n):
4 yield call(i)
5 print("i=",i)
6 print("done.")
7
8 def call(i):
9 return i*2
10
11 for i in yield_test(5):
12 print(i,",")
>>>什麼是生成器?0 ,
i= 0
2 ,
i= 1
4 ,
i= 2
6 ,
i= 3
8 ,
i= 4
done.
>>>
生成器僅僅儲存了一套生成數值的演算法,並且沒有讓這個演算法現在就開始執行,而是我什麼時候調它,它什麼時候開始計算乙個新的值,並給你返回。
def count_down(n):結果:while n >= 0:
newn = yield n
print('newn', newn)
if newn:
print('if')
n = newn
print('n =', n)
else:
n -= 1
cd = count_down(5)
for i in cd:
print(i, ',')
if i == 5:
cd.send(3)
理解 Python 生成器
什麼時候呼叫,什麼時候計算並返回值 生成器僅僅儲存了一套生成數值的演算法,並且沒有讓這個演算法現在就開始執行,而是我什麼時候調它,它什麼時候開始計算乙個新的值,並給你返回。在python中,一邊迴圈一邊計算的機制,稱為生成器 generator。列表耗記憶體 列表所有資料都在記憶體中,如果有海量資料...
對生成器的理解
迭代器 對於可迭代物件使用內建函式iter 獲取迭代器物件。迭代器物件通過next 方法來訪問裡面的元素 當容器中沒有可訪問的元素後,next 方法將會丟擲乙個stopiteration異常終止迭代器。列表生成式 例 x 2 for x in range n 生成器表示式 通列表解析語法,把列表解析...
對於生成器的理解
什麼是生成器呢?生成器就是一次生成乙個值的函式 就像是一把自動步槍,生成器中的值就它的子彈,槍平時都會有保險,在關保險的時候怎麼扣扳機都不會射出子彈 而自動步槍呢還可以單點和全自動兩個模式進行射擊.舉個例子 def func for i in range 100 yield i 這就是個簡單的生成器...