對于Python新手來說,寫代碼很少考慮代碼的效率和簡潔性,因此容易造成代碼冗長、執(zhí)行慢,這些都是需要改進的地方。本文是想通過幾個案列給新手一點啟發(fā),怎樣寫python代碼更優(yōu)雅。
01.不喜歡使用高級數據結構
sets(集合)
很多新手忽視sets(集合)和tuple(元組)的強大之處.
例如,取兩個列表交集:
defcommon_elements(list1,list2):
common=[]
foritem1inlist1:
ifitem1inlist2:
common.append(item1)、
returncommon
這樣寫會更好:
defcommon_elements(list1,list2):
common=set(list1).intersection(set(list2))
returnlist(common)
dic(字典)
新手枚舉(訪問和取出)字典的鍵和對應值,認為對應值必須通過鍵來訪問,往往會這樣做:
my_dict={'a':1,'b':2}
forkeyinmy_dict:
print(key,my_dict[key])
有一個更優(yōu)雅的方法可以實現:
my_dict={'a':1,'b':2}
forkey,valueinmy_dict.items():
print(key,value)
對大部分項目來說,這樣寫會更加有效率。
tuple(元組)
元組一旦創(chuàng)建就無法更改元素,看似沒有什么用處,其實元組的作用大著呢!很多函數方法都會返回元組,比如enumerate()和dict.items(),并且可以在函數中使用元組,返回多個值。還能夠很方便地從元組中提取信息:
a,b=('cat','dog')
上面元組中有兩個元素,分別被賦給a,b。如果有多個值,同樣可以提取:
a,b,c=('cat','dog','tiger')
print(a,b,c)
提取首、尾兩個元素:
first,*_,end=(1,2,3,4,5,6)
print(first,end)
#輸出:1、6
提取首、中、尾三部分:
first,*middle,end=(1,2,3,4,5,6)
print(first,middle,end)
#輸出:1、[2,3,4,5]、6
元組還可以用來交換變量:
(a,b,c)=(c,a,b)
上面a變成之前的c,b變成之前的a,c變成之前的b。元組也能作為字典的鍵,所以如果你需要存儲數據,可以使用帶有元組鍵的字典,比如說經緯度數據。
02.不喜歡使用上下文管理器
新手可能會習慣這樣進行讀取文件操作:
ifos.path.exists(data_file_path):
data_file=open(data_file_path,'r')
else:
raiseOSERROR
print(data_file.read())
data.close()
這樣寫會有幾個明顯的問題:
·可能出現文件存在,但文件被占用,無法讀取的情況
·可能出現文件可以被讀取,但操作文件對象出現報錯的情況
·可能出現忘記關閉文件的情況
如果使用with…語句,問題就迎刃而解了:
withopen(data_file_path,'r')asdata_file:
print(data_file.read)
這樣可以捕獲任何打開文件或處理數據時的異常情況,并且在任務處理完后自動關閉文件。
python初學者可能不太了解上下文管理器的神奇之處,它真的能帶來巨大的便利。
03.不喜歡使用標準庫
標準庫itertools和collections仍然很少被初學者使用
itertools
如果你看到下面的任務:
list1=range(1,10)
list2=range(10,20)
foritem1inlist1:
foritem2inlist1:
print(item1*item2)
這是一個嵌套循環(huán)操作,為提高代碼效率,完全可以用product()函數替代嵌套循環(huán):
fromitertoolsimportproduct
list1=range(1,10)
list2=range(10,20)
foritem1,item2inproduct(list1,list2):
print(item1*item2)
這兩段代碼的結果完全一樣,但使用標準庫函數明顯更加簡潔高效。itertools還有很多方便操作迭代對象的函數,比如:
·count()函數會創(chuàng)建一個無限迭代器
·cycle()函數會把傳入的序列無限重復下去
·chain()可以把多個迭代對象串聯起來
·group()函數可以把迭代其中相鄰的重復元素挑出來,放在一起
有興趣可以詳細看看itertools庫的各種神奇函數。
collections
新手對python集合模塊了解的可能并不多,你可能會遇到這樣的情形:
consolidated_list=[('a',1),('b',2),('c',3),('b',4)]
items_by_id={}
forid_,iteminconsolidated_list:
ifid_notinitems_by_id:
items_by_id[id_]=[]
ifid_initems_by_id:
items_by_id[id_].append(item)
上面代碼構建了一個字典,依次向字典中添加信息,如果某個鍵已經存在,則以某種方式修改該鍵的值;如果某個鍵不存在,則添加對應鍵值對。
這種算法非常常見,你可以用collects模塊的defaultdict()函數來實現同樣效果:
fromcollectionsimportdefaultdict
items_by_id=defaultdict(list)
consolidated_list=[('a',1),('b',2),('c',3),('b',4)]
forid_,iteminconsolidated_list:
items_by_id[id_].append(item)
在此列中,defaultdict()接受一個list作為參數,當鍵不存在時,則返回一個空列表作為對應值。
有時候我們會遇到統(tǒng)計詞頻的案例,比如:
#統(tǒng)計詞頻
colors=['red','blue','red','green','blue','blue']
result={}
forcolorincolors:
ifresult.get(color)==None:
result[color]=1
else:
result[color]+=1
print(result)
#輸出{'red':2,'blue':3,'green':1}
完全可以用defaultdict()函數實現上面的計數功能:
colors=['red','blue','red','green','blue','blue']
d=defaultdict(int)
forcolorincolors:
d[color]+=1
print(d)
更簡單的方法用collections模塊的Counter()函數:
fromcollectionsimportCounter
colors=['red','blue','red','green','blue','blue']
c=Counter(colors)
print(dict(c))
對于備份文件,新人往往會用system模塊:
fromosimportsystem
system("xcopye:\\sample.csve:\\newfile\\")
其實shutil模塊更好用:
importshutil
shutil.copyfile('E:\\q.csv','e:\\movie\\q.csv')
因為shutil會很詳細地報告錯誤和異常。
04.不喜歡使用異常處理
無論老手新手都應該在寫代碼的時候進行異常處理操作,這樣可以使代碼更加健壯。異常處理一般會用try…except語句。
05.:不喜歡使用生成器
除非你的list十分復雜,并且頻繁調用,否則都建議使用生成器,因為它非常節(jié)省內存,舉個例子:
defpowers_of_two(max=20000):
i=0
powers=[]
while2**i powers.append[2**i] i+=1 returnpowers 對于使用次數少、占據大量內存、且容易生成的數據,可以用生成器替代列表存儲: fromitertoolsimportcount,takewhile defpowers_of_two(max=20000): forindexintakewhile(lambdai:2**i yield2**index 以上內容為大家介紹了Python新手的五大坑,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。http://m.fengjieshuijing.cn/