Python 學習筆記 - 生成器和迭代器

這一節來學習生成器(generator)和迭代器(iterator)


首先來回憶一個例子,這裏打印rest的時候爲什麼要通過list(rest)打出,而不是直接輸出rest?


>>> li=[11,22,33]
rest=filter(lambda x:x>22,li)
print(list(rest))
--------
[33]


試試看,如果直接輸出是什麼結果?

>>> li=[11,22,33]
rest=filter(lambda x:x>22,li)
print(rest)
<filter object at 0x00000192C88AF4A8>


事實上,如果在2.7裏面,他會直接輸出結果,但是在3.X以後,他只會返回一個具有生成能力的對象,而不是直接輸出所有結果,這樣的好處是如果我們有成千上萬個數據要輸出,他不會直接一股腦的就輸出來了。我們需要循環地輸出這個對象生成所有需要的值。比如把上面的例子改成for循環也是一樣的

>>> li=[11,22,33]
rest=filter(lambda x:x>22,li)
for i in rest:
    print(i)
33


現在來看看基本的定義:


1.迭代器是訪問集合元素的一種方式。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因爲人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可以不存在或者被銷燬。這個特點使得它特別適合用於遍歷一些巨大的或是無限的集合,比如幾個G的文件

特點:

  1. 訪問者不需要關心迭代器內部的結構,僅需通過next()方法不斷去取下一個內容

  2. 不能隨機訪問集合中的某個值 ,只能從頭到尾依次訪問

  3. 訪問到一半時不能往回退

  4. 便於循環比較大的數據集合,節省內存



2. 一個函數調用時返回一個迭代器,那這個函數就叫做生成器(generator);如果函數中包含yield語法,那這個函數就會變成生成器;


下面直接通過例子說明:

比如我定義了一個函數f1,裏面包含了yield這個關鍵字,那麼他就變成了一個生成器,他的結果只能通過迭代器的next方法一步步輸出

>>> def f1():
    print("1")
    yield 22
    print("2")
    yield 33
    print("3")
    yield 44
r=f1()
print(r,type(r))
print(r.__next__())
print(r.__next__())
print(r.__next__())
--------------------
<generator object f1 at 0x00000192C88DC728> <class 'generator'>
1
22
2
33
3

當然通過循環語句自動調用迭代器更方便了

for item in r:
    print(item)


例2 通過生成器做一個range的函數

>>> def nrange(num):
    temp = -1
    while True:
        temp = temp + 1
        if temp >= num:
            return
        else:
            yield temp
r=nrange(5)
print(r)
for item in r:
    print(item)
---------------------
<generator object nrange at 0x00000192C88DC360>
0
1
2
3
4


再看個例子

def split_line():
    print ('ready to split')
    result="4 5 6"
    while True:
        line=yield result
        result=line.split()
s=split_line()
s.__next__()
#send的值去替換掉line的值,返回值是result
ret=s.send('1 2 3')
print(ret)
ret=s.send('a b c')
print(ret)
"C:\Program Files\Python3\python.exe" C:/Users/yli/pycharmprojects/Exercise/Week12/test.py
ready to split
----------
['1', '2', '3']
['a', 'b', 'c']


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