Python 3 中生成器函式yield表示式的使用

覆手為雲p發表於2017-04-27

 

生成器函式或生成器方法中包含了一個yield表示式。呼叫生成器函式時,會返回一個迭代子,值從迭代子中每次提取一個(通過呼叫其__next__()方法)。每次呼叫__next__()時,生成器函式的yield表示式的值(如果未指定就是None)都會返回。如果生成器函式結束或執行一個return,就產生StopIteration異常。

上面的說法有點官方,下邊是一些個人的理解:

1、當一個函式中包含有yield表示式時,在呼叫這個呼叫這個函式時,函式的程式碼並不會執行,而是返回一個迭代子,或者說是一個可用於迭代的容器(相當於一個陣列的序列數)。如下面這個例子,當呼叫a()時並沒有執行程式碼

>>> def a():

            print('a')

            yield 'x'

>>> a()

<generator object a at 0x0000027BBFB380F8>

>>>     

 

2、要想使這個函式執行起來,就需要一個迭代器來讀取這個容器內的內容,比如說for語句,如下:

>>> for i in a():
             i

a
'x'
>>>     

 

 

3、一個yield表示式只會產生“一個“迭代子,再解釋一下,這個迭代子就同於序列[‘a’,’b’,’c’]中‘a’,’b’,’c’的位置引數0,1,2。如果有多個迭代子,當呼叫迭代器時,就會有多次迭代:

def b():

    print('a')

    yield 1

    print('b')

    yield 3

for i in b():

    print(i)

a

1

b

3

>>> 

 

例子中的for迴圈執行了兩次,第一次迭代的是yield 1產生的迭代子(也可以簡單的把它理解為序列的第一個序列號0),返回了結果1和yield 表示式前邊的print(‘a’) 的結果,第二次迭代的是yield 3表示式產生的迭代子,結果為yield 3表示式的返回值3和它前邊的語句print(‘b’)的結果。

4、yield在一定程度上也有return的作用——都會返回一個值(即上面函式的‘x’)但yield不會終止函式,而是使函式暫停,直到所有的迭代子都被使用後,就會產生一個StopIteration異常,從而終止函式

5、用iter函式來檢視可迭代結構的具體過程。

用a=iter(iterable結構)可以獲取一個迭代子,在每次迴圈時可用next(a)方法獲取下一個資料項,當結尾時會產生一個StopIteration異常。

函式b()相當於一個包含了兩個迭代子的容器;

>>> c=iter(b())

>>> next(c)

a

1

>>> next(c)

b

3

>>> next(c)

Traceback (most recent call last):

File "<pyshell#6>", line 1, in <module>

next(c)

StopIteration

>>> 

 

第一次和第二次迭代分別返回兩個迭代子的結果,當所有的迭代子都已使用時,第三次迭代就產生了一個StopIteration。

6、yield返回的就是迭代子的值,yield可以將任意內容設定為迭代子。大多數情況下我們理解的迭代子都是0,1,2,3,4...這樣的自然位置迭代,而yield就把它設定為任意的值,a()函式生成的迭代子為 ‘x’,b()函式生成的迭代子為1,3。

相關文章