學習7: 列表生成式,生成器,迭代器,可迭代對象

1) 列表生成式,即建立列表的方式算法

列表生成式,這裏是中括號[]數據結構

>>> [x*x for x in range(0,10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
>>> 

2) 生成器(Generator)
生成器有兩種方法:第一個是經過生成器表達式來建立,另一種是經過定義帶有yield的函數來實現。函數

生成器, 這裏是小括號()spa

>>> (x*x for x in range(0,10))
<generator object <genexpr> at 0x0000000000C15240>
>>> 

說明:從這個能夠看出生成器和列表生成的區別:列表生成式直接返回了表達式的結果列表, 而生成器是一個對象,該對象包含了對錶達式結果的計算引用。
前者若是數據量太大時候會佔用很大內存,而生成器保存的只是一個計算對象,不會佔用很大內存。code

若是上述算法比較複雜,很差寫在一個(),那麼可使用定義一個包含yield的函數來實現,這個就是第二種實現方法。
若是一個函數定義中包含了yield關鍵字,這個函數就再也不是普通函數,而是一個generator object。
要想調用這個函數,須要使用next()函數,而且遇到yield語句返回(能夠把yield理解爲return)。例如:對象

def test():
    print "one"
    yield 
    print "two"
    yield 
    print 'three'
    yield
t=test()
t.next()
t.next()

輸出結果爲:
one
two
[Finished in 0.2s]blog

說明:首先建立生成器對象實例t,而後經過next方法調用函數,每一次執行到yield語句會被終止,並在下次該實例再次執行next方法時候繼續執行。因此第一個next方法打印one,第二個next打印two.
test().next()
test().next()
輸出結果爲:
one
one
[Finished in 0.2s]
說明:注意必須是同一個實例不斷調用next方法,如上這種調用方法達不到想要的效果。three

def test():
    print "one"
    yield 
    print "two"
    return
    print "testing"
    yield 
    print 'three'
    yield
t= test()
t.next()
t.next()

說明:若是生成器中有return,在執行過程當中 return,則直接拋出 StopIteration 終止迭代。內存

 

def readfile(file_name):
    seek_option=0
    while True:
        with open(file_name) as f:
            f.seek(seek_option)
            data = f.readline()
            if data:
                yield data
                seek_option = f.tell()
            else:
                return
print readfile('README.md')
file = readfile('README.md')
for data in file:
    print data
for data in readfile('README.md'):
    print data

說明: 上述定義了一個讀取文件的生成器。生成器通常能夠和for循環配合使用,這樣能夠迭代生成器元素,而不使用next方法。generator

 

3)迭代器(Iterators)
任何具備__next__()方法的對象都是迭代器。
因此生成器是一種特殊的迭代器,任意一個生成器都屬於迭代器。

 

4)可迭代對象
可迭代對象能夠爲任意對象,不必定非得是基本數據結構,只要這個對象能夠返回一個iterator。
可迭代對象經過iter函數能夠轉化爲迭代器,以下例a是一個可迭代對象,而b是一個迭代器。
實際在for循環的過程當中也都是將可迭代對象首先轉化成迭代器,而後經過next方法讀取元素直到拋出異常。

>>> a=[1,2,3,4]
>>> b=iter(a)
>>> type(a)
<type 'list'>
>>> type(b)
<type 'listiterator'>
>>> b.next()
1
>>> b.next()
2
>>> 
相關文章
相關標籤/搜索