1、迭代器
迭代是Python最強大的功能之一,是訪問集合元素的一種方式。。
迭代器是一個可以記住遍歷的位置的對象。
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會后退。
迭代器有兩個基本的方法:iter() 生成迭代器和 next()遍歷迭代器元素。
>>> dil = iter(range(10)) #使用iter方法創建一個迭代器 >>> print(type(dil)) #類型為迭代器 <class 'range_iterator'> >>> print(dil) <range_iterator object at 0x7fb9bf466ed0> >>> l1 = [1,2,3,4,5] >>> it = iter(l1) #將列表轉換為迭代器 >>> print(type(it)) <class 'list_iterator'> >>> print(it) <list_iterator object at 0x7fb9bf42e9e8> >>> print(next(it)) 1 >>> print(next(it)) 2 >>> print(next(it)) 3 >>> print(next(it)) 4 >>> print(next(it)) 5 >>> print(next(it)) #如果迭代器元素到最后沒有了就會報錯 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> for i in it: #此處因為迭代元素已經到了最后,所以沒有元素輸出 ... print(i,end=" ") ... >>> print(next(dil)) #使用next輸出迭代器的下一個元素 0 >>> print(next(dil)) 1 >>> print(next(dil)) 2 >>> print(next(dil)) 3 >>> for i in dil: #而輸出dil迭代器的元素會接着輸出迭代器的元素,知道最后一個。 ... print(i,end=" ") ... 4 5 6 7 8 9 >>> >>> list = [1,2,3,4,5,6,7,8] >>> inter1 = list.__iter__() #遵循迭代器協議,生成可以迭代的對象 >>> print(inter1.__next__()) 1 >>> print(inter1.__next__()) 2 #集合中使用迭代器 >>> s1 = {'python','java','net','php'} >>> iter2 = s1.__iter__() >>> print(iter2) <set_iterator object at 0x7fb9bf450ea0> >>> print(iter2.__next__()) java >>> print(iter2.__next__()) php >>> print(iter2.__next__()) net >>> print(iter2.__next__()) python >>> print(iter2.__next__()) #字典中使用迭代器 >>> dict1 = {'k1':'v1','k2':'v2'} >>> iter3 = dict1.__iter__() >>> print(iter3.__next__()) #字典默認迭代的是key值 k1 >>> print(iter3.__next__()) k2 #文件中使用迭代器 >>> with open('test','r') as f1: ... iter5 = f1.__iter__() ... print(iter5.__next__(),end = ' ') ... print(iter5.__next__(),end = ' ') ... print(iter5.__next__(),end = ' ') ... 11111 2222 33333 4444 55555 6666
2、生成器
在 Python 中,使用了 yield 的函數被稱為生成器(generator)。
跟普通函數不同的是,生成器是一個返回迭代器的函數,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。
在調用生成器運行的過程中,每次遇到 yield 時函數會暫停並保存當前所有的運行信息,返回yield的值。並在下一次執行 next()方法時從當前位置繼續運行。
生成器可以理解為一種數據類型,這種數據類型自動實現了迭代器協議(其他的數據類型需要調用自己內置的__iter__方法),所以生成器就是可迭代對象
生成器分類及在python中的表現形式:(Python有兩種不同的方式提供生成器)
1.生成器函數:常規函數定義,但是,使用yield語句而不是return語句返回結果。yield語句一次返回一個結果,在每個結果中間,掛起函數的狀態,以便下次重它離開的地方繼續執行
2.生成器表達式:類似於列表推導,但是,生成器返回按需產生結果的一個對象,而不是一次構建一個結果列表
為何使用生成器之生成器的優點
Python使用生成器對延遲操作提供了支持。所謂延遲操作,是指在需要的時候才產生結果,而不是立即產生結果。這也是生成器的主要好處。
生成器小結:
1.是可迭代對象
2.實現了延遲計算,省內存啊
3.生成器本質和其他的數據類型一樣,都是實現了迭代器協議,只不過生成器附加了一個延遲計算省內存的好處
def ite(): print('hello') yield 'test1' print('world') yield 'test2' yield 'test3' yield 'test4' gen = ite() #生成了一個生成器 print(type(gen)) print(gen.__next__()) print(gen.__next__()) print(gen.__next__()) print(gen.__next__()) <class 'generator'> hello test1 world test2 test3 test4
生成器方法:
close():手動關閉生成器,后面的調用會直接返回Stoplteration異常。
>>> def gen(): ... yield 'hello' ... yield 'python' ... >>> st = gen() >>> print(st.__next__()) hello >>> st.close() #關閉生成器后再顯示元素就拋出異常 >>> print(st.__next__()) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
send():生成器函數最大的特點是可以接受外部傳入的一個變量,並根據變量內容計算結果后返回。
def consumer(name): print('begin..') while True: baozi = yield name #第一次執行時返回name的值,然后將send的值賦值給yield print('is you %s' %baozi) #所以此時baozi的值為1 d = consumer('zhang') print(d.__next__()) print(d.send(1)) print(d.send(2)) print(d.send(3)) print(d.send(5)) begin.. zhang is you 1 zhang is you 2 zhang is you 3 zhang is you 5 zhang
throw():用來想生成器函數傳入一個異常,可以結束系統定義的異常,或者自定義的異常。
throw()后直接拋出異常並結束程序,或者消耗掉一個yield,或者在沒有下一個yield的時候直接進行到程序的結尾。