python新手遇到的5大坑
對(duì)于Python新手來(lái)說(shuō),寫代碼很少考慮代碼的效率和簡(jiǎn)潔性,因此容易造成代碼冗長(zhǎng)、執(zhí)行慢,這些都是需要改進(jìn)的地方。本文是想通過(guò)幾個(gè)案列給新手一點(diǎn)啟發(fā),怎樣寫python代碼更優(yōu)雅。
一:不喜歡使用高級(jí)數(shù)據(jù)結(jié)構(gòu)
sets(集合)
很多新手忽視sets(集合)和tuple(元組)的強(qiáng)大之處
例如,取兩個(gè)列表交集:
def common_elements(list1, list2): common = [] for item1 in list1: if item1 in list2: common.append( item1 ) return common這樣寫會(huì)更好:
def common_elements(list1, list2):common = set(list1).intersection(set(list2))return list(common)dic(字典)
新手枚舉(訪問(wèn)和取出)字典的鍵和對(duì)應(yīng)值,認(rèn)為對(duì)應(yīng)值必須通過(guò)鍵來(lái)訪問(wèn),往往會(huì)這樣做:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' my_dict = {'a':1,'b':2} for key in my_dict: print(key, my_dict[key])有一個(gè)更優(yōu)雅的方法可以實(shí)現(xiàn):
my_dict = {'a':1,'b':2}for key, value in my_dict.items(): print(key, value)對(duì)大部分項(xiàng)目來(lái)說(shuō),這樣寫會(huì)更加有效率。
tuple(元組)
元組一旦創(chuàng)建就無(wú)法更改元素,看似沒(méi)有什么用處,其實(shí)元組的作用大著呢!很多函數(shù)方法都會(huì)返回元組,比如enumerate()和dict.items(),并且可以在函數(shù)中使用元組,返回多個(gè)值。還能夠很方便地從元組中提取信息:
a,b = ('cat','dog')上面元組中有兩個(gè)元素,分別被賦給a,b。如果有多個(gè)值,同樣可以提取:
a,b,c = ('cat','dog','tiger') print(a,b,c)提取首、尾兩個(gè)元素:
first,*_,end = (1,2,3,4,5,6) print(first,end) # 輸出:1、6提取首、中、尾三部分:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' first,*middle,end = (1,2,3,4,5,6) print(first,middle,end) # 輸出:1、[2, 3, 4, 5]、6元組還可以用來(lái)交換變量:
(a,b,c) = (c,a,b)上面a變成之前的c,b變成之前的a,c變成之前的b
元組也能作為字典的鍵,所以如果你需要存儲(chǔ)數(shù)據(jù),可以使用帶有元組鍵的字典,比如說(shuō)經(jīng)緯度數(shù)據(jù)。
二:不喜歡使用上下文管理器
新手可能會(huì)習(xí)慣這樣進(jìn)行讀取文件操作:
if os.path.exists(data_file_path): data_file = open(data_file_path,'r') else: raise OSERROR print( data_file.read()) data.close()這樣寫會(huì)有幾個(gè)明顯的問(wèn)題:
- 可能出現(xiàn)文件存在,但文件被占用,無(wú)法讀取的情況
- 可能出現(xiàn)文件可以被讀取,但操作文件對(duì)象出現(xiàn)報(bào)錯(cuò)的情況
- 可能出現(xiàn)忘記關(guān)閉文件的情況
如果使用with…語(yǔ)句,問(wèn)題就迎刃而解了:
with open(data_file_path,'r') as data_file:print(data_file.read)這樣可以捕獲任何打開(kāi)文件或處理數(shù)據(jù)時(shí)的異常情況,并且在任務(wù)處理完后自動(dòng)關(guān)閉文件。
python初學(xué)者可能不太了解上下文管理器的神奇之處,它真的能帶來(lái)巨大的便利。
三:不喜歡使用標(biāo)準(zhǔn)庫(kù)
標(biāo)準(zhǔn)庫(kù)itertools和collections仍然很少被初學(xué)者使用
itertools
如果你看到下面的任務(wù):
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' list1 = range(1,10) list2 = range(10,20) for item1 in list1:for item2 in list1:print(item1*item2)這是一個(gè)嵌套循環(huán)操作,為提高代碼效率,完全可以用product()函數(shù)替代嵌套循環(huán):
from itertools import product list1 = range(1,10) list2 = range(10,20) for item1,item2 in product(list1, list2):print(item1*item2)這兩段代碼的結(jié)果完全一樣,但使用標(biāo)準(zhǔn)庫(kù)函數(shù)明顯更加簡(jiǎn)潔高效。itertools還有很多方便操作迭代對(duì)象的函數(shù),比如:
- count()函數(shù)會(huì)創(chuàng)建一個(gè)無(wú)限迭代器
- cycle()函數(shù)會(huì)把傳入的序列無(wú)限重復(fù)下去
- chain()可以把多個(gè)迭代對(duì)象串聯(lián)起來(lái)
- group()函數(shù)可以把迭代其中相鄰的重復(fù)元素挑出來(lái),放在一起
- …
有興趣可以詳細(xì)看看itertools庫(kù)的各種神奇函數(shù)
collections
新手對(duì)python集合模塊了解的可能并不多,你可能會(huì)遇到這樣的情形:
consolidated_list = [('a',1),('b',2),('c',3),('b',4)] items_by_id = {} for id_, item in consolidated_list:if id_ not in items_by_id: items_by_id[id_] = []if id_ in items_by_id:items_by_id[id_].append(item)上面代碼構(gòu)建了一個(gè)字典,依次向字典中添加信息,如果某個(gè)鍵已經(jīng)存在,則以某種方式修改該鍵的值;如果某個(gè)鍵不存在,則添加對(duì)應(yīng)鍵值對(duì)。
這種算法非常常見(jiàn),你可以用collects模塊的defaultdict()函數(shù)來(lái)實(shí)現(xiàn)同樣效果:
from collections import defaultdictitems_by_id = defaultdict(list) consolidated_list = [('a',1),('b',2),('c',3),('b',4)]for id_, item in consolidated_list:items_by_id[id_].append(item)在此列中,defaultdict()接受一個(gè)list作為參數(shù),當(dāng)鍵不存在時(shí),則返回一個(gè)空列表作為對(duì)應(yīng)值。
有時(shí)候我們會(huì)遇到統(tǒng)計(jì)詞頻的案例,比如:
# 統(tǒng)計(jì)詞頻 colors = ['red', 'blue', 'red', 'green', 'blue', 'blue'] result = {} for color in colors:if result.get(color)==None:result[color]=1else:result[color]+=1 print (result) # 輸出 {'red': 2, 'blue': 3, 'green': 1}完全可以用defaultdict()函數(shù)實(shí)現(xiàn)上面的計(jì)數(shù)功能:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' colors = ['red', 'blue', 'red', 'green', 'blue', 'blue'] d = defaultdict(int) for color in colors:d[color] += 1 print(d)更簡(jiǎn)單的方法用collections模塊的Counter()函數(shù):
from collections import Counter colors = ['red', 'blue', 'red', 'green', 'blue', 'blue'] c = Counter(colors) print (dict(c))對(duì)于備份文件,新人往往會(huì)用system模塊:
from os import system system("xcopy e:\\sample.csv e:\\newfile\\")其實(shí)shutil模塊更好用:
import shutil shutil.copyfile('E:\\q.csv', 'e:\\movie\\q.csv')因?yàn)閟hutil會(huì)很詳細(xì)地報(bào)告錯(cuò)誤和異常。
四:不喜歡使用異常處理
無(wú)論老手新手都應(yīng)該在寫代碼的時(shí)候進(jìn)行異常處理操作,這樣可以使代碼更加健壯。異常處理一般會(huì)用try…except語(yǔ)句,具體使用方法可見(jiàn):
五:不喜歡使用生成器
除非你的list十分復(fù)雜,并且頻繁調(diào)用,否則都建議使用生成器,因?yàn)樗浅9?jié)省內(nèi)存,舉個(gè)例子:
def powers_of_two(max=20000):i = 0powers = []while 2**i < max:powers.append[2**i]i += 1return powers對(duì)于使用次數(shù)少、占據(jù)大量?jī)?nèi)存、且容易生成的數(shù)據(jù),可以用生成器替代列表存儲(chǔ):
from itertools import count, takewhile def powers_of_two(max=20000):for index in takewhile(lambda i: 2**i < max, count(start=0)):yield 2**index總結(jié)
以上是生活随笔為你收集整理的python新手遇到的5大坑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python类三种方法,函数传参,类与实
- 下一篇: python 序列解包(解压缩)