對于Python新手來說,寫代碼很少考慮代碼的效率和簡潔性,因此容易造成代碼冗長、執行慢,這些都是需要改進的地方,本文是想通過幾個案列給新手一點啟發,怎樣寫python代碼更優雅,
大坑一:不喜歡使用高級資料結構
1.sets(集合)
很多新手忽視sets(集合)和tuple(元組)的強大之處
例如,取兩個串列交集:
def common_elements(list1, list2):
common = []
for item1 in list1:
if item1 in list2:
common.append( item1 ) 、
return common
這樣寫會更好:
def common_elements(list1, list2):
common = set(list1).intersection(set(list2))
return list(common)
2.dic(字典)
新手列舉(訪問和取出)字典的鍵和對應值,認為對應值必須通過鍵來訪問,往往會這樣做:
my_dict = {'a':1,'b':2}
for key in my_dict:
print(key, my_dict[key])
有一個更優雅的方法可以實作:
my_dict = {'a':1,'b':2}
for key, value in my_dict.items():
print(key, value)
對大部分專案來說,這樣寫會更加有效率,
3.tuple(元組)
元組一旦創建就無法更改元素,看似沒有什么用處,其實元組的作用大著呢!很多函式方法都會回傳元組,比如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
元組也能作為字典的鍵,所以如果你需要存盤資料,可以使用帶有元組鍵的字典,比如說經緯度資料,
大坑二:不喜歡使用背景關系管理器
新手可能會習慣這樣進行讀取檔案操作:
if os.path.exists(data_file_path):
data_file = open(data_file_path,'r')
else:
raise OSERROR
print( data_file.read())
data.close()
這樣寫會有幾個明顯的問題:
- 可能出現檔案存在,但檔案被占用,無法讀取的情況
- 可能出現檔案可以被讀取,但操作檔案物件出現報錯的情況
- 可能出現忘記關閉檔案的情況
如果使用with...陳述句,問題就迎刃而解了:
with open(data_file_path,'r') as data_file:
print(data_file.read)
這樣可以捕獲任何打開檔案或處理資料時的例外情況,并且在任務處理完后自動關閉檔案,
python初學者可能不太了解背景關系管理器的神奇之處,它真的能帶來巨大的便利,
大坑三:不喜歡使用標準庫
標準庫itertools和collections仍然很少被初學者使用
itertools
如果你看到下面的任務:
list1 = range(1,10)
list2 = range(10,20)
for item1 in list1:
for item2 in list1:
print(item1*item2)
這是一個嵌套回圈操作,為提高代碼效率,完全可以用product()函式替代嵌套回圈:
from itertools import product
list1 = range(1,10)
list2 = range(10,20)
for item1,item2 in product(list1, list2):
print(item1*item2)
這兩段代碼的結果完全一樣,但使用標準庫函式明顯更加簡潔高效,itertools還有很多方便操作迭代物件的函式,比如:
- count()函式會創建一個無限迭代器
- cycle()函式會把傳入的序列無限重復下去
- chain()可以把多個迭代物件串聯起來
- group()函式可以把迭代其中相鄰的重復元素挑出來,放在一起
......
有興趣可以詳細看看itertools庫的各種神奇函式
collections
新手對python集合模塊了解的可能并不多,你可能會遇到這樣的情形:
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)
上面代碼構建了一個字典,依次向字典中添加資訊,如果某個鍵已經存在,則以某種方式修改該鍵的值;如果某個鍵不存在,則添加對應鍵值對,
這種演算法非常常見,你可以用collects模塊的defaultdict()函式來實作同樣效果:
from collections import defaultdict
items_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()接受一個list作為引數,當鍵不存在時,則回傳一個空串列作為對應值,
有時候我們會遇到統計詞頻的案例,比如:
# 統計詞頻
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
result = {}
for color in colors:
if result.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)
for color in colors:
d[color] += 1
print(d) #學習中遇到問題沒人解答?小編創建了一個Python學習交流群:711312441
更簡單的方法用collections模塊的Counter()函式:
from collections import Counter
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
c = Counter(colors)
print (dict(c))
對于備份檔案,新人往往會用system模塊:
from os import system
system("xcopy e:\\sample.csv e:\\newfile\\")
其實shutil模塊更好用:
import shutil
shutil.copyfile('E:\\q.csv', 'e:\\movie\\q.csv')
因為shutil會很詳細地報告錯誤和例外,
大坑四:不喜歡使用例外處理
無論老手新手都應該在寫代碼的時候進行例外處理操作,這樣可以使代碼更加健壯,例外處理一般會用try...except陳述句
大坑五:不喜歡使用生成器
除非你的list十分復雜,并且頻繁呼叫,否則都建議使用生成器,因為它非常節省記憶體,舉個例子:
def powers_of_two(max=20000):
i = 0
powers = []
while 2**i < max:
powers.append[2**i]
i += 1
return powers
對于使用次數少、占據大量記憶體、且容易生成的資料,可以用生成器替代串列存盤:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543600.html
標籤:Python
上一篇:使用gensim框架和隨機文本訓練Word2Vector模型
下一篇:類和類的定義
