標籤:else 函數 stdout toolbar lag function result lambda 序列
1、三元運算式:
value= true-expr if condition else false-expr
例如:a=‘positive‘ if 3>0 else ‘negative‘
2、用列表推導式來取代map和filter
a=[1,2,3,4,5]squares=list(map(lambda x:x**2,a))print(squares) #[1, 4, 9, 16, 25]squares=[x**2 for x in a]print(squares) #[1, 4, 9, 16, 25]data=list(map(lambda x:x**2 ,filter(lambda x:x%2==0,a)))print(data) #[4, 16]data_one=[x**2 for x in a if x%2==0] 等價於data_one=[x**2 for x in a and x%2==0]
print(data_one) #[4, 16] #字典與集合也有類似的推導機制 chile_ranks={‘ghost‘:1,‘habanero‘:2,‘cayenne‘:3} rank_dict={rank:name for name,rank in chile_ranks.items()} chile_len_set={len(name) for name in rank_dict.values()} print(rank_dict) #{1: ‘ghost‘, 2: ‘habanero‘, 3: ‘cayenne‘} print(chile_len_set) #{8, 5, 7}3、函數式編程
能接收其他函數作為參數的函數,被稱為高階函數(high-order function)
代表性高階函數:map() filter() 和 reduce()
map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,
並把結果作為新的Iterable返回。
lambda_sum=lambda x,y:x+yprint(lambda_sum(3,4)) #7data_list=[1,3,5,6]result=map(lambda x:x+3,data_list)print(list(result)) #[4, 6, 8, 9]def f(x): return x+3result_one=list(map(f,data_list))print(result_one) #[4, 6, 8, 9]
reduce():把一個函數作用在一個序列[x1,x2,x3,...]上,這個函數必須接收兩個參數,reduce把結果
繼續和序列的下一個元素做累積計算。感覺用處不大!自己也能寫,會麻煩一些,如果需要,還是可用。
from functools import reducedata_list=[1,3,5]print(reduce(lambda x,y:2*x+y,data_list)) #15def f_reduce(x,y): return 2*x+yprint(reduce(f_reduce,data_list)) #15new_list=data_list[:1]for i in range(1,len(data_list)): new_list.append(2*new_list[i-1]+data_list[i])print(new_list) #[1, 5, 15]print(new_list[-1]) #15def prod(L): new_list=L[:1] for i in range(1,len(L)): new_list.append(new_list[i-1]*L[i]) return new_list[-1]print(prod([3, 5, 7, 9])) #945def prod(L): return reduce(lambda x,y:x*y,L)print(prod([3, 5, 7, 9])) #945
3、filter() ,和map()類似,也接收一個函數和一個序列。和map()不同的是,filter()把傳入的函數依次作用於每個元素,
然後根據傳回值是True還是False決定保留還是丟棄該元素
list(filter(lambda x:x%2==0,[3,4,5])) #[4]list(filter(lambda x:x%2==1,[3,4,5])) #[3,5]
lst=[x**2 for x in range(10)] #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]x1=[1,3,5]y1=[9,12,13]lst1=[x**2 for (x,y) in zip(x1,y1) if y>10]print(lst1) #[9, 25]dict={k:v for k,v in enumerate(‘vamei‘) if v not in ‘vi‘}print(dict) #{1: ‘a‘, 2: ‘m‘, 3: ‘e‘}4、fluent python 閱讀筆記
import os,time,sys,requestsPOP20_CC=(‘CN IN US ID BR PK NG BD RU JP ‘‘MX PH VN ET EG DE IR TR CD FR‘).split()BASE_URL=‘http://flupy.org/data/flags‘DEST_DIR=‘E://‘def save_flag(img,filename): path=os.path.join(DEST_DIR,filename) with open(path,‘wb‘) as fp: fp.write(img)def get_flag(cc): url=‘{}/{cc}/{cc}.gif‘.format(BASE_URL, cc=cc.lower()) resp=requests.get(url) return resp.contentdef show(text): print(text,end=‘ ‘) sys.stdout.flush()def download_many(cc_list): for cc in sorted(cc_list): image=get_flag(cc) show(cc) save_flag(image,cc.lower()+‘.gif‘) return len(cc_list)def main(download_many): t0=time.time() count=download_many(POP20_CC) elapsed=time.time()-t0 msg=‘\n{} flags downloaded in {:.2f}‘ print(msg.format(count,elapsed))if __name__==‘__main__‘: main(download_many)
簡單的一個代碼,寫的比較好!將一個指令碼任務按照實現流程分為幾個動作,每個動作寫一個函數,有如下優點:
1、代碼清晰
思路清晰,而非鬍子眉毛一把抓,整體任務分為若干個小動作,一個動作用一個函數來實現。
2、易於擴充
如果代碼某一塊需要修改,可以僅修改部分函數即可,對其他函數無影響,也可以增加其他功能。
3、寫主函數
代碼中包含有主函數,從主函數開始,便於程式的閱讀,一看到main(),知道從這裡開始閱讀起。
4、不同函數之間變數名稱
寫函數的時候可以以變數名稱、類型方式寫,注意函數內變數一致即可,調用時則使用全域變數中名稱,兩者要不一樣嗎?為什麼呢??
比如這樣改寫download_many函數:
def download_many(POP20_CC):
for cc in sorted(POP20_CC): image=get_flag(cc) show(cc) save_flag(image,cc.lower()+‘.gif‘) return len(POP20_CC)
如果我們修改主函數,下載10個國家國旗圖片
POP10_CC=(‘CN IN US ID BR PK NG BD RU JP‘).split()
def main(download_many): t0=time.time() count=download_many(POP10_CC) elapsed=time.time()-t0 msg=‘\n{} flags downloaded in {:.2f}‘ print(msg.format(count,elapsed))
結果是主函數的修改對download_many函數還是起作用,因為download_many函數中變數只是相當於x,真正起作用還是調用時主函數中輸入的參數值,所以你這樣寫也沒有問題。不過用變數cc_list好,閱讀起來不會引起混淆,不管你是下10國國旗還是20國國旗。如果你download_many中是20國國旗作為變數,調用時輸入10國國旗為參數,看起來比較彆扭。
自己以後寫代碼要學習這種寫法!
python文法技巧