列表生成式是 python 內置的很是簡單卻強大的能夠用來建立list的生成式。python
有這樣一個需求:
l1 = [1,2,3,4,5,6,7,8,9] 循環每一個元素加1ide
l1 = [1,2,3,4,5,6,7,8,9] # 使用列表生成式將列表中的各個元素加1 list_num = [x+1 for x in l1] # 這裏就是一個列表生成式 print(list_num)
列表生成式能夠用一行語句代替循環生成上面的list函數
迭代器表面上看是一個數據流對象或容器,當使用其中的數據時,每次從數據流中取出一個數據,直到數據被取完,並且數據不會被重複使用。
從代碼的角度來看,迭代器是實現了迭代器協議方法的對象和類。
迭代器協議方法主要是兩個:
__iter__(): 該方法返回對象自己,它是for語言使用迭代器的要求,只要函數含有__iter__就能夠說這個函數是可迭代的;
__next__(): 該方法用於返回容器中下一個元素或數據。當容器中的數據用盡時,應該引起 StopIteration 異常一個類只要具備這兩種方法,就能夠稱之爲 迭代器,也能夠說是可迭代的。spa
s1 = 'hello world' print('__iter__' in dir(s1)) print('__next__' in dir(s1)) # 字符串s1包含 __iter__ 方法且不包含__next__方法,因此字符串 s1 只是一個可迭代的類型,並非一個迭代器 # 執行結果: # True # False
s1 = 'hello world' s2 = s1.__iter__() # 將可迭代類型轉換爲 迭代器 使用 __iter__() print('__iter__' in dir(s2)) print('__next__' in dir(s2)) # 使用 __iter__()方法將 s1 字符串轉換爲迭代器,迭代器既有__iter__方法,又有 __next__方法 # 執行結果: # True # True
自定義一個迭代器必須知足:
類中必需要定義 __iter__ 方法和 __next__方法code
# 自定義一個迭代器: class My_iterator(object): def __init__(self, x, max): self.mul, self.x = x, x self.xmax = max def __iter__(self): return self def __next__(self): if self.x and self.x !=1: self.mul = self.mul + self.x if self.mul < self.xmax: return self.mul else: raise StopIteration if __name__ == '__main__': myite1 = My_iterator(2, 100) for i in myite1: print(i)
迭代器必定是可迭代的, 可是可迭代的不必定是迭代器對象
使用生成器能夠生成一個值的序列用於迭代,而且這個值的序列不是一次生成的,而是使用一個,再生成一個,可使得程序節約大量內存。
生成器對象是經過yield關鍵字定義的函數對象,所以生成器也是一個函數。生成器用於生成一個值的序列,以便在迭代中使用。blog
自定義生成器:內存
def foo(): print('1111') yield 1 print('22222') yield 2 f = foo() print('type f:', type(f)) print(f.__next__()) print(f.__next__()) # 執行結果: # type f: <class 'generator'> # 1111 # 1 # 22222 # 2
執行流程以下圖:字符串
須要注意的是 yield 是生成器中的關鍵字,生成器在實例化的時候並不會當即執行,而是等待調用其__next__()方法以後纔開始運行,當再次調用__next__()方法會在第一次yield返回值的最後開始執行,不斷的調用__next__()方法,直到最終返回 StopIteration 異常爲止。generator
實例1:移動平均值
# 移動平均值 def foo(): ''' sum 計算總和 count 計算有幾個數 avg 平均數 :yield: 返回計算出的平均數 ''' sum = 0 count = 0 avg = 0 while True: num = yield avg # 接收num,返回avg sum += num count += 1 avg = sum / count f = foo() next(f) ret = f.send(10) print(ret) ret = f.send(20) print(ret) ret = f.send(30) print(ret) ret = f.send(40) print(ret) # 執行結果: # 10.0 # 15.0 # 20.0 # 25.0