當咱們調用yield,它究竟作了什麼

顯然,要理解yield,首先要了解迭代器(iterator),接着瞭解什麼是生成器(generator)。python

迭代器

通俗的講,迭代器就是能夠逐個訪問的容器,而逐個逐步訪問的過程成爲迭代。git

iterator = [item for item in range(5)]
for i in iterator:
    print(i)
0
1
2
3
4

生成器

上述代碼中,iterator就是一個迭代器,for循環部分就是迭代過程。生成器一樣也是可供迭代訪問的容器,與迭代器不一樣的是,生成器中的元素不會一次性存入內潤中,而是一邊迭代一邊生成。github

generator = (item for item in range(5))
for i in generator:
    print(i)
0
1
2
3
4

迭代器和生成器的執行效率

由於生成器邊迭代邊生成,因此佔用內存極少,執行效率也更高。函數

def go_thru_iterator(item_len):
    iterator = [item for item in range(item_len)]
    for i in iterator:
        pass
def go_thru_generator(item_len):
    generator = (item for item in range(item_len))
    for i in generator:
        pass
%time go_thru_iterator(100000000)
CPU times: user 12 s, sys: 11.8 s, total: 23.8 s
Wall time: 23.8 s
%time go_thru_generator(100000000)
CPU times: user 12.7 s, sys: 0 ns, total: 12.7 s
Wall time: 12.6 s

yield

yield的使用和return的使用沒有什麼區別,只是yield會返回一個生成器。當代碼執行到yield時,該函數會返回yield以後的值,並在原地等待下一次迭代;當執行到下一次迭代時,代碼接着上一次等待的地方執行:code

  • 若使用生成器的send方法,則yield語句的返回值send中的參數
  • 若使用next函數迭代,則在yield的返回值爲None

注: next至關於mgen.send(None),但mgen.send在生成器第一次迭代時不可調用內存

def create_generator():
    mylist = range(3)
    for i in mylist:
        ret = yield i * i
        print('ret:', ret)
mgen = create_generator()
next(mgen)
0
next(mgen)
ret: None
1
mgen.send('The yield return value.')
ret: The yield return value.
4
try:
    next(mgen)
except StopIteration:
    print('Already arrive the end of the generator element.')
ret: None
Already arrive the end of the generator element.

原文地址:github:jasonTu/python-material-collection 當咱們調用yield,它究竟作了什麼element

相關文章
相關標籤/搜索