疊代器
-
概述
疊代器是通路集合元素的一種方式。疊代器對象從集合的第一個元素開始通路,直到所有的元素被通路完結束。疊代器隻能往前不會後退。
-
可疊代對象
疊代器提供了一個統一的通路集合的接口。隻要是實作了__iter__()或 getitem()方法的對象,就可以使用疊代器進行通路。
序列:字元串、清單、元組
非序列:字典、檔案
自定義類:使用者自定義的類實作了__iter__()或__getitem__()方法的對象
疊代字典
d = {'a': 1, 'b': 2, 'c': 3} for k in d: print(k) for k in d.keys(): print(k) for v in d.values(): print(v) for (k,v) in d.items(): print(k,v)
- 疊代基礎
f1=open('data.txt') # for line in f1.readlines(): #把所有行讀入記憶體,遇到大檔案效率差 # print(line) # for line in f1: # print(line) # 檔案對象就是自己的疊代器 print(f1.__next__()) print(f1.__next__()) # 為了手動支援疊代,python3.0提供了一個next()方法,他會自動調用對象的_next_() print(next(f1))
-
iter() 和 next()
字元串/數組本身沒有疊代對象
s='hello' iter01=iter(s) print(next(iter01)) print(next(iter01)) arr=[1,2,3,4] E=iter(arr) # print(E.__next__()) # print(next(E)) while True: try: X=E.__next__() except StopIteration: break print(X)
字典對象有一個疊代器,每次傳回字典的key
params={'name':'tom','age':12} for key in params: ... #是以不要下面的寫法 for key in params.keys(): ...
-
range()
range()支援多個疊代器,而其他内置函數不支援
arr=list(range(20)) print(arr) R=iter(range(100)) print(next(R)) print(next(R)) print(next(R))
-
map() zip() filter()
和range()不同,以上三個函數都是自己的疊代器
M=map(abs,[2,-3,-1,3]) print(next(M))
itertools
itertools 是python的疊代器子產品,itertools提供的工具相當高效且節省記憶體
###無限疊代的疊代器
-
count(初值=0, 步長=1)
無限疊代
from itertools import count for i in count(10): #從10開始無限循環 if i > 20: break # pass else: print(i)
-
slice(count(10), 5)
從 10 開始,輸出 5 個元素後結束。islice 的第二個參數控制何時停止疊代。但其含義并不是”達到數字 5 時停止“,而是”當疊代了 5 次之後停止“。
from itertools import count,islice for i in islice(count(10), 5): print(i)
- cycle()
from itertools import cycle count = 0 for item in cycle('XYZ'): if count > 7: break print(item) count += 1
這裡我們建立了一個 for 循環,使其在三個字母 XYZ 間無限循環。當然,我們并不真地想要永遠循環下去,是以我們添加了一個簡單的計數器來跳出循環。
###可終止疊代器
-
accumulate(可疊代對象[, 函數])
accumulate 疊代器将傳回累計求和結果,或者傳入兩個參數的話,由傳入的函數累積計算的結果。預設設定為相加,我們趕快試一試吧:
這裡,我們 導入了 accumulate,然後傳入 10 個數字,0-9。疊代器将傳入數字依次累加,是以第一個是 0 ,第二個是 0+1, 第三個是 1+2,如此下去。現在我們導入 operator 子產品,然後添加進去:>> from itertools import accumulate >>> list(accumulate(range(10))) [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
>>> import operator >>> list(accumulate(range(1, 5), operator.mul)) [1, 2, 6, 24]
這裡我們傳入了數字 1-4 到 accumulate 疊代器中。我們還傳入了一個函數:operator.mul,這個函數将接收的參數相乘。是以每一次疊代,疊代器将以乘法代替除法(1×1=1, 1×2=2, 2×3=6, 以此類推)。
accumulate 的文檔中給出了其他一些有趣的例子,例如貸款分期償還,混沌遞推關系等。這絕對值得你花時間去看一看。
-
combinations(iterable, r)
方法可以建立一個疊代器,傳回iterable中所有長度為r的子序列,傳回的子序列中的項按輸入iterable中的順序排序。
實作一組資料的所有排列組合import itertools list1 = [1, 3, 4, 5] list2 = list(itertools.combinations(list1, 2)) print(list2) 傳回結果: [(1, 3), (1, 4), (1, 5), (3, 4), (3, 5), (4, 5)]
import itertools list1 = [1, 3, 4, 5] list2 = [] for i in range(1, len(list1)+1): iter1 = itertools.combinations(list1, i) list2.append(list(iter1)) print(list2) 傳回結果: [[(1,), (3,), (4,), (5,)], [(1, 3), (1, 4), (1, 5), (3, 4), (3, 5), (4, 5)], [(1, 3, 4), (1, 3, 5), (1, 4, 5), (3, 4, 5)], [(1, 3, 4, 5)]]
#排列組合
-
Python内置的排列組合函數有四個:
product 笛卡爾積 (有放回抽樣排列)
permutations 排列 (不放回抽樣排列)
combinations 組合,沒有重複 (不放回抽樣組合)
combinations_with_replacement 組合,有重複 (有放回抽樣組合)
permutations 在數學中可以了解為:A(3|4)=4*3*2=24
combinations 在數學中可以了解為:C(3|4)=C(1|4)=4
例題如下:
from itertools import combinations ,permutations
list01 = [1, 2, 3, 5,]
a = list(combinations(list01,3))
b = list(permutations(list01,3))
print(a) #[(1, 2, 3), (1, 2, 5), (1, 3, 5), (2, 3, 5)]
print(b) #[(1, 2, 3), (1, 2, 5), (1, 3, 2), (1, 3, 5), (1, 5, 2), (1, 5, 3), (2, 1, 3), (2, 1, 5), (2, 3, 1), (2, 3, 5), (2, 5, 1), (2, 5, 3), (3, 1, 2), (3, 1, 5), (3, 2, 1), (3, 2, 5), (3, 5, 1), (3, 5, 2), (5, 1, 2), (5, 1, 3), (5, 2, 1), (5, 2, 3), (5, 3, 1), (5, 3, 2)]
print(len(b)) #24