拓展:itertools包
標準庫中的itertools包提供了更加靈活的生成迭代器的工具
這些工具的輸入大都是已有的迭代器,另一方面
這些工具完全可以自行使用py實現(xiàn)
該包只是提供了一種比較標準,高效的實現(xiàn)方式
這也符合py“只有且最好只有一個解決方案”的理念
#引入itertools
from itertools import *
這個包中提供了很多有用的生成器
下面兩個生成器能返回?zé)o限循環(huán)的迭代器:
count(5,2) #從5開始的整數(shù)迭代器,每次增加2,即5,7,9,11,13...
cycle('abc') #重復(fù)序列的元素,即a,b,c,a,b,c...
repeat()既可以返回一個不斷重復(fù)的迭代器,也可以是有次數(shù)限制的重復(fù):
repeat(1,2) #重復(fù)1.2,構(gòu)成無窮迭代器,即1.2,1.2,1.2,...
repeat(10,5) #重復(fù)10,共重復(fù)5次
我們還能組合舊的迭代器,來生成新的迭代器:
chain([1,2,3],[4,5,6]) #連接兩個迭代器成為一個 1,2,3,4,5,6
product("abc",[1,2]) #多個迭代器集合的笛卡爾積,相當(dāng)于嵌套循環(huán)
所謂的笛卡爾積可以得出集合所有可能的組合方式:
for m,n in product("abc",[1,2]):
print(m,n)
如下所示:
permutations("abc",2) #從'abc'中挑選兩個元素,比如ab,bc,...
#將上面所有結(jié)果排序,返回為新的迭代器
#上面的組合區(qū)分順序,即ab,ba都返回
combinations("abc",2) 從'abc'中挑選兩個元素,比如ab,bc,...
#將上面所有結(jié)果排序,返回為新的迭代器
#上面的組合不分順序
#即ab,ba,只返回一個ab
combinations_with_replacement("abc",2) #與上面類似
#但允許兩次選出的元素重復(fù)
#即多了,aa,bb,cc

如圖所示
itertools包中還提供了許多有用的高階函數(shù):
starmap(pow,[(1,1),(2,2),(3,3)]) #pow將依次作用于表的每個tuple
takewhile(lambda x:x < 5,[1,3,6,7,1])
#當(dāng)函數(shù)返回True時,收集元素到迭代器,一旦函數(shù)返回False,則停止。1,3
dropwhile(lambda x:x < 5,[1,3,6,7,1])
#跳過元素,一旦函數(shù)返回True,則開始收集剩下的所有元素到迭代器。6,7,1
包中提供了groupby()函數(shù),能將一個key()函數(shù)作用于原迭代器的各個元素
從而獲得各個函數(shù)的鍵值,根據(jù)key()函數(shù)結(jié)果,將擁有元素分組
每個分組中的元素都保留了鍵值相同的返回結(jié)果
函數(shù)groupby()分出的組放在一個迭代器中返回
如果有一個迭代器,包含一群人的身高,我們可以使用這樣的一個key()函數(shù):
如果身高大于180,返回"tall";如果身高低于160,返回"short";
中間的返回"middle",最終,所有身高將分為三個迭代器
即"tall","short","middle"
from itertools import groupby
def height_class(h):
if h > 180:
return "tall"
elif h < 160:
return "short"
else:
return "middle"
friends = [191,158,159,165,170,177,181,182,190]
friends = sorted(friends,key = height_class)
for m,n in groupby(friends,key = height_class):
print(m)
print(list(n))
middle
[165, 170, 177]
short
[158, 159]
tall
[191, 181, 182, 190]
注意:groupby()的功能類似于UNIX中的uniq命令
分組之前需要使用sorted()對原迭代器的元素
根據(jù)key()函數(shù)進行排序,讓同組元素先在位置上靠攏
這個包中還有其他一些工具,方便迭代器的構(gòu)建:
compress("abcd",[1,1,1,0]) #根據(jù)[1,1,1,0]的真假值情況,選擇
#保留第一個參數(shù)中的元素,a,b,c
islice() #類似于slice()函數(shù),只是返回的是一個迭代器
izip() #類似于zip()函數(shù),只是返回的是一個迭代器