17. Python 產生式 產生器 迭代器

來源:互聯網
上載者:User

標籤:python   產生器   迭代器   

1.      產生式和產生器

列表產生式是python受歡迎的一種文法之一,通過一句簡潔的文法,就能對元組元素進行過濾,還可以對得到的元素進行轉換處理。

文法格式:

    [exp for val in collection if condition]

相當於

result = []

for val in collection:

    if (condition):

        result.append(exp)


例子:

    a = [x*x for x in xrange(10) if x%2 == 0]

    print (type(a))

    print (a)

結果:

    <type ‘list‘>

    [0, 4, 16, 36, 64]

解釋:

① 由此取出xrange(10)從0到9

② 判斷 x*x 是偶數,就保留,存在新的字典中

③ 把所有符合x*x是偶數的元素都放到新的列表中返回。


通過列表產生式,我們可以建立一個列表,但是,受到記憶體限制,列表容量肯定是有限的;

如果建立一個包含100萬個元素的的列表,不僅佔用很大的儲存空間,當我們僅僅需要訪問前面的幾個元素,後面絕大多數元素占的空間都浪費了。


所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素?

這樣一來就不必建立完整的list了,從而節省大量的空間。

在python中,這種一邊迴圈一邊計算的機制,稱為"產生器"(Generator)


產生器是一次產生一個值的特殊類型函數,可以將其視為可繼續函式,調用該函數將返回一個可用於產生連續 x 的值的產生器;

簡單的說就是在函數執行過程中,yield 語句會把你需要的的值返回給調用產生器的地方,然後退出函數,下次調用產生器函數

的時候,又從上次中斷的地方開始執行,而產生器內的所有變數參數會被儲存下來供下一次使用。


要建立產生器有好幾種方法:

第一種方法

    把一個列表產生式的[],改成(),這就建立了一個產生器。

例子:

lst = (x*x for x in xrange(1,101) if x%2 == 0)

print (lst)

print (type(lst))

print (lst.next())

print (lst.next())

print (lst.next())

print (lst.next())

print (lst.next())

print (lst.next())

結果:

<generator object <genexpr> at 0x02E72508>

<type ‘generator‘>

4

16

36

64

100

144


解釋:

    generator 儲存的是演算法,每次調用next(),就計算出下一個元素的值,直到計算到最後一個元素為止。


第二種方法:

函數中定義清單產生器,即如果函數中包含yield關鍵字,那麼這個函數不再是一個普通函數,而是一個generator。


普通函數:

def func(n):

    sum = 0

    i = 0

    while(i<n):

        sum = sum + i

        i += 1

        print (sum)

func(10)

結果:

0

1

3

6

10

15

21

28

36

45


清單產生器:

def func(n):

    sum = 0

    i = 0

    while(i<n):

        sum = sum + i

        i += 1

        yield (sum)

for x in func(10):

    print  x

print (type(func(10)))


結果:

0

1

3

6

10

15

21

28

36

45


解釋:

① 以上函數有關鍵字 yield ,所以產生的是一個產生器;

② 通過for 迴圈調用產生器,當執行到yield的時候,返回sum值,sum為0,此時暫停並記錄sum的值;

③ 列印出sum的值,然後繼續往下去執行,跳入下一個迴圈 while(1<10)

④ 直到遇到yield的時候,返回sum的值

⑤ 反覆執行3,4的步驟,直到迴圈結束,最終退出程式。


兩個函數的區別:

    一個直接反回了運算式的結果清單,另一個是一個對象,該對象包含了對錶達式結果的計算引用,通過迴圈可以直接輸出。

產生器不會一次性列出所有資料,當你用到的時候,再列出來,更加節約記憶體使用量率。


普通函數和清單產生器的區別:

    結果雖然相同,但是包含yield語句的函數會特地編譯成產生器,當函數被調用的時候,他們返回一個產生器對象,這個對象支援迭代器介面,

每當遇到yield關鍵字的時候,可以理解成函數的return語句,yield後面的值,就是傳回值。但是不像一般函數在return後退出,產生器函數在產生

值後會自動掛起並暫停他們的執行和狀態,他的本地變數將儲存狀態資訊,這些資訊在函數恢複時將再度有效,下次從yield下面的部分開始執行。

比如說上一次執行到3,下次開始時,找到3的位置,從6開始執行,(不會從頭開始執行),以此類推。


補充學習:http://www.jianshu.com/p/d09778f4e055

產生式:一次性產生所有資料,然後儲存在記憶體中,適合小量的資料。

產生器:返回一個可迭代的對象,即"generator"對象,必須通過迴圈才可以一一列出所有結果。


2.      迭代器

iterable (可迭代對象) 和 iterator(迭代器)主要區別:

凡是可以用 for 迴圈的都是iterable(可迭代對象),可以通過迴圈調用出來的都是,比如:[],(),{},產生式....

凡是要通過 next()函數調用並獲得值的可迭代對象都是iterator(迭代器)

所以產生器可以被next()函數調用並不斷返回下一個值的對象稱為迭代器

可以簡單理解為 產生器 就是迭代器的可迭代對象。


凡是可作用於 for 迴圈的對象都是iterable 類

凡是可作用於 next()函數的對象都是iterator類型,他們表示一個惰性計算的序列。



作業:

九九乘法表

def func(n):

    return ["{0}*{1}={2}".format(x,n,x*n) for x in xrange(1,n+1) ]


for i in xrange(1,10):

    print " ".join(func(i))


本文出自 “筆記空間” 部落格,請務必保留此出處http://286577399.blog.51cto.com/10467610/1978911

17. Python 產生式   產生器   迭代器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.