生成式 - 生成器 - 迭代器 - 裝飾器

1. 生成式

通過列表生成式,我們可以直接創建一個列表。格式是:[exp for val in collection if condition]

相當於

result=[]
for val in collection:
    if(condition):
        result.append(exp)

例子:

list1 = [x*x for x in xrange(1,11) if x %2 == 0]
print (type(list1))
print (list1)

結果:

<type 'list'>
[4, 16, 36, 64, 100]

##通過生成式創建的列表,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅佔用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。


2.生成器

如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器(Generator)。


a.創建一個生成器

第一種方法是把一個列表生成式的[]改成(),就創建了一個generator

list1 = (x*x for x in xrange(1,11) if x %2 == 0)
print (type(list1))
print (list1.next())
print (list1.next())
print (list1.next())
print (list1.next())
print (list1.next())
結果:

<type 'generator'>
4
16
36
64
100
解釋:generator保存的是算法,每次調用next(),就計算出下一個元素的值,直到計算到最後一個元素爲止.

b.第二種方法,如果一個函數定義中包含yield關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator

yield的使用例子

def fun(n):
    sum = 0
    i = 0
    while i < n:
        sum += i
        i += 1
        print (sum)
fun(10)
結果爲:

0
1
3
6
10
15
21
28
36
45

這個程序就是求09所有數字之和,接下來,我們只要稍微改動一下,你看看有什麼差別,

def fun(n):
    sum = 0
    i = 0
    while i < n:
        sum += i
        i += 1
        yield(sum)
for x in fun(10):
    print(x)
print(type(fun(10)))
結果爲:

0
1
3
6
10
15
21
28
36
45
<type 'generator'>

結果和上面的結果是一樣的,包含yield語句的函數會被特地編譯成生成器。當函數被調用時,他們返回一個生成器對象,這個對象支持迭代器接口。每當遇到yield關鍵字的時候,你可以理解成函數的return語句,yield後面的值,就是返回的值。但是不像一般的函數在return後退出,生成器函數在生成值後會自動掛起並暫停他們的執行和狀態,他的本地變量將保存狀態信息,這些信息在函數恢復時將再度有效,下次從yield下面的部分開始執行。

解釋:

1.以上函數有關鍵字yield,所以生成的是一個生成器。

2.通過for循環調用生成器,當執行到yield的時候,返回sum的值,sum0,此時暫停並記錄sum的值

3.打印sum的值,然後繼續往下執行。此時跳入下一個循環while(1<10)

4.直到遇到yield的時候,返回sum的值。

5.反覆執行3,4步驟,知道循環結束,最終程序退出


生成式與生成器的區別:

一個直接返回了表達式的結果列表, 而另一個是一個對象,該對象包含了對錶達式結果的計算引用, 通過循環可以直接輸出

生成器不會一次性列出所有的數據,當你用到的時候,在列出來,更加節約內存的使用率。



3.迭代器
Iterable(可迭代對象和Iterator(迭代器)主要區別是 :

凡是可以用 for 循環的 都是  Iterable(可迭代對象)凡是需要通過next()函數獲得值的可迭代對象都是 Iterator(迭代器)。

(所以生成器可以 next()函數調用並不斷返回下一個值的對象稱爲迭代器 ) (可以簡單理解爲生成器 就是 迭代器的可迭代對象)

 凡是可作用於for循環的對象都是Iterable類型;

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

a = [1,2,3,4,5]
print type(a)
b = iter(a)
print type(b)
結果爲

<type 'list'>
<type 'listiterator'>




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章