迭代器,生成器,列表推導式,生成器表達式

迭代器:

可迭代對象:內部含有__inter__的python

可迭代對象不能取值,由於內部沒有__next__()方法app

可迭代對象------>迭代器:ssh

  boj.__iter__()或者inter(obj)ide

實現的原理相似於往彈匣裏面裝子彈,而後一個一個往外發射函數

經過__iter__()來獲取到迭代器spa

1 stes = {1, 2, 3, 4, 5, 67, 7} 2 print(stes.__dir__()) 3 s = stes.__iter__() 4 print(s)
迭代器

打印結果code

1 ['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__sub__', '__rsub__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__isub__', '__iand__', '__ixor__', '__ior__', '__len__', '__contains__', '__new__', 'add', 'clear', 'copy', 'discard', 'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', '__reduce__', 'remove', '__sizeof__', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__'] 2 <set_iterator object at 0x0000000001EF1480>
打印結果

經過__next__()來拿到元素,一次只能拿一個,若是最後一個元素以後繼續使用__next__(),會報錯:StopIterationorm

 1 stes = {1, 2, 3, 4, 5, 67, 7}  2 s = stes.__iter__()  3 print(s.__next__())  4 print(s.__next__())  5 print(s.__next__())  6 print(s.__next__())  7 print(s.__next__())  8 print(s.__next__())  9 print(s.__next__()) 10 print(s.__next__())
__next__()

打印結果爲:對象

 1 1
 2 2
 3 3
 4 4
 5 5
 6 67
 7 7
 8 Traceback (most recent call last):  9   File "C:/Python/Module/regex_test.py", line 53, in <module>
10     print(s.__next__()) 11 StopIteration
打印結果

判斷是否爲迭代器:blog

  1.經過__iter__(),__next__()是否在obj.__dir__()

1 with open('01','w', encoding='utf-8') as f: 2     print('__iter__' in dir(f)) 3     print('__next__' in dir(f)) 4 """
5 打印結果: 6 True 7 True 8 說明文件句柄自己是一個迭代器 9 """
dir方法

  2.經過collections模塊中的Iterable來判斷

 1 from collections import Iterable  2 from collections import Iterator  3 
 4 l = [1,2,3,4]  5 print(isinstance(l, Iterable))    # 判斷是否爲可迭代對象
 6 print(isinstance(l, list))  7 
 8 
 9 """
10 打印結果: 11 True 12 True 13 """
14 
15 l = [1,2,3,4] 16 print(isinstance(l, Iterable)) 17 print(isinstance(l, Iterator)) 18 print(isinstance(l, list)) 19 
20 """
21 打印結果: 22 True 23 False 24 True 25 """
Iterable

 

生成器:

生成器實質就是迭代器,在python中有三種方式來獲取生成器:

1. 經過生成器函數
2. 經過各類推導式來實現來生成器
3. 經過數據的轉換也能夠獲取生成器

 生成器是咱們本身用Python代碼寫的迭代器:

 1 def gener():  2     print(111)  3     yield 222
 4     print(333)  5     yield 444
 6     print(555)  7     yield 666
 8     print(777)  9     yield 888
10 
11 
12 gen = gener() 13 print(gen) 14 
15 # 打印結果爲:<generator object gener at 0x0000000001E74D00>
生成器

生成器函數和普通的函數的區別就是把return換成了yield

 yield 和return區別

  1. 若是函數中包含了yield, 這個函數是一個生成器函數. 執行函數的時候是: 生成器

  2. 生成器執行__next__(). 執行到下一個yield

  3. yield的做用和return基本相同. 可是,只負責返回. 不會結束函數

  4. return,結束函數.

經過obj__next__()方法取值:

 1 def gener():  2     print(111)  3     yield 222
 4     print(333)  5     yield 444
 6     print(555)  7     yield 666
 8     print(777)  9     yield 888
10 
11 
12 gen = gener() 13 print(gen) 14 ret = gen.__next__()    # 這裏的ret至關於執行函數,直行道yield是返回yield的返回值
15 print(ret) 16 ret1 = gen.__next__() 17 print(ret1) 18 ret2 = gen.__next__() 19 print(ret2) 20 ret3 = gen.__next__() 21 print(ret3) 22 
23 """
24 打印結果: 25 <generator object gener at 0x0000000000814D00> 26 111 27 222 28 333 29 444 30 555 31 666 32 777 33 888 34 """
生成器取值

生成器還能夠經過send()方法進行取值個傳值,不過使用send方法時要注意的是:

  1.第一個yield必須經過__next__()方法取得

  2.最後一個yield不能經過send()方法傳值.

 1 def gener():  2     print(111)  3     a = yield 222
 4     print(a)  5     print(333)  6     b = yield 444
 7     print(b)  8     print(555)  9     c = yield 666
10     print(c) 11     print(777) 12     yield 888
13 
14 
15 gen = gener() 16 print(gen) 17 ret = gen.__next__() 18 print(ret) 19 ret1 = gen.send('<<>>') 20 print(ret1) 21 ret2 = gen.send('<<>>') 22 print(ret2) 23 ret3 = gen.send('<<>>') 24 print(ret3) 25 
26 """
27 打印結果: 28 <generator object gener at 0x0000000001DD4D00> 29 111 30 222 31 <<>> 32 333 33 444 34 <<>> 35 555 36 666 37 <<>> 38 777 39 888 40 """
send()方法

使用send()方法時要注意的是要傳參,否則會報錯

send和__next__() 區別:

  send能夠給上一個yield 的位置傳遞值 , 第一個必須用__next__()

  __next__() 不能傳值

列表推導式:

須要一個列表,裏面包含1到13的數字,第一反應是:

1 l = [] 2 
3 for i in range(1, 14): 4  l.append(i) 5 print(l) 6 # 打印結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
生成一個列表

 咱們來看這樣一段代碼:

1 l = [ i for i in range(1,14)] 2 print(l) 3 
4 #打印結果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
列表推導式

有這樣一個需求,經過列表推導式來篩選憨厚兩個e的名字:

1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], 2          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] 3 name2 = [name for i in names for name in i if name.count('e') == 2] 4 print(name2) 5 
6 # 打印結果:['Jefferson', 'Wesley', 'Steven', 'Jennifer']
篩選模式

l = [變量(加工後的變量) for 變量 in iterable] 循環模式

l = [變量(加工後的變量) for 變量 in iterable if 條件] 篩選模式

相似於真樣的式子被成爲列表推導式.

優勢:

1,節省代碼,一行搞定.

2,看着高大上.

缺點:

很差排錯.

總體:

凡是用列表推導式構造的列表對象,用其餘方式均可構建.,很是複雜的列表,列表推導式是構建不出的,

列表推導式比較有魔性.

生成器表達式:

生成器表達式和列表推導式基本同樣,惟一的區別就是把列表推推導式的方括號變成圓括號:

1 l = ( i for i in range(1,14)) 2 print(l) 3 
4 #打印結果:<generator object <genexpr> at 0x0000000001F24D00>
生成器表達式

 

一樣的也有兩種模式:

循環模式和篩選模式

相關文章
相關標籤/搜索