生成器yield關鍵字作用和理解
生成器yield關鍵字作用和理解
yield關鍵字的一個功能就是能有效地降低迭代的記憶體開銷。
如果使用range函式的話,那麼函式的內部實現會儲存每個迭代的過程,即每個中間變數有個記憶體空間,這樣首先程式使用的記憶體空間就大了,而且分配記憶體、回收記憶體都會導致程式的執行時間加長。但是使用yield實現的xrange函式的話,裡面所有中間變數都會只使用一個記憶體¥i,這樣需要的時間和空間都會變小。
在瞭解yield和迭代:
迭代是一種對資料的操作,例如針對一個list逐一獲取其中的元素的過程就叫做迭代。而可迭代是物件的一種特性,迭代操作只能針對擁有可迭代特性的物件進行,常見的可迭代物件包括陣列、元組、字典等資料集合。
迭代器也是一種可迭代物件,與普通的可迭代物件的區別在於,迭代器內部實現了next函式用來生成每次迭代迴圈需要返回的元素。而最後的生成器則又是一種特殊的迭代器,具體體現上就是使用yield語法的函式,講到這裡就提到了yield語法,總的來說yield就是用來產生一個生成器的語法,例如將上述的迭代過程修改為生成器方式可以這樣寫:
上述程式碼的my_generator()即返回了一個生成器物件,每次迴圈時執行到yield處即返回當時的index的值,到下一次迴圈時將從上次返回的yield處繼續執行,直到index的值不滿足小於5的條件時結束整個函式,此時也結束了對這個生成器的迭代過程。
(瞭解yield和迭代內容選自http://wemedia.ifeng.com/93602193/wemedia.shtml)
那麼為什麼要使用yield:
因為省記憶體呀!例如上述兩個迭代過程,同樣是遍歷輸出0-4這幾個元素,使用列表的方式需要構建出一個長度為5的陣列並存儲在記憶體中,而使用生成器的方式只需要一個index變數即可實現,這還是迭代元素較少的情況下,如果迭代的是100萬甚至1000萬個元素時,列表的方式就需要構建一個長度為100萬或者1000萬的陣列,這時對於記憶體的使用就是非常大的負擔了,而使用生成器的方式,無論是迭代100萬還是1000萬個元素,依然只需要一個index變數即可實現。
再舉個例子,for迴圈從1到10每次加1迴圈,不用yield關鍵字時,i=1,分配給他一個記憶體空間,進行判斷符合,將i=1傳入執行方法,執行完方法後i++,判斷2符合,然後將i=2傳入執行方法,分配給他一個記憶體空間……這樣我們在1、2、3、4、5、6、7、8、9、10每次判斷都分配了記憶體空間,是使用“列表”方法構建了一個數組一樣的結構;而使用yield關鍵字時,他是隻用一個記憶體空間的,具體到這個例子他是先指定一個記憶體空間,執行方法,然後將i=1傳入,判斷為true,執行方法,然後i++為2,判斷符合傳入剛才那個記憶體空間再執行方法。