用python也有小兩年了,不是開發,所以代碼應該沒那麼精湛。但是經常會寫測試指令碼和小工具。在積累了大量的庫以後,開始把重點放在提高python效率的方法,養成好的習慣。因為是剛剛開始關注,所以不斷補充吧,以便將來隨時查看。
一.原則類
1.把range全部換成xrange
2.產生器,如 list=(item for item in fp)
3.利用psyco庫,提高函數和類的運行效率。
4.字串拼接:盡量少用“+”的方式,而採用''.join ,還有"%s"%i這樣賦值的手段
5.函數的開銷很大。盡量把迴圈放在函數內進行。而不要讓每次迭代都調用函數。
6.“前提工作”先做好,比如該賦值,該拼接的,然後再引入到函數中,或者進行下面的迴圈。
7.盡量使用內建方法,因為內建的是C寫的,效率肯定高很多
8.每當要對序列中的內容進行迴圈處理時,就應當嘗試用列表解析來代替它,如:[i for i in xrang(10) if i%2==0]
9.學會使用itertools模組。當python中添加了迭代器後,就為常見模式提供了一個新的模組,因為它是以C語言編寫,所以提供了最高效的迭代器。
--多記錄一些。列表,字串,字典,xrange,類檔案對象,這些都是可迭代對象,換句話說,都可以直接用在for迴圈中進行迭代,如for item in open('1.txt')
--直接使用速度會快。另外,我對比了itertools裡工具和xrange,比如都迴圈100000次列印數字,使用islice(count(),100000)均要比xrange(100000)快
--而xrange還要比range快。
10.用列表解析取代for迴圈。列表解析的效率等於或高於map。
11.記憶體回收機制,會對列表的操作有重大影響,如列表的append,或者列表解析。import gc,然後在資料載入模組前gc.disable(),結束後再gc.enable()。
二.應用類
1.列表推導
如果想複製一個列表或者字典,直接使用L1=list(L),d1 = dict(d).而不要使用列表推導。
如果想對列表的每一個元素都調用函數,應該用L1=map(f,L),而不是L1=[f(x) for x in L]
當序列過長,每次只需要讀取一個元素的時候,應該用產生器,而不是列表推導。total=sum(x+23 for x in lodlist if x >5)
2.從檔案中讀取指定的行
標準庫linecache非常適合這個任務:
import linecache
theline = linecache.getline(thefilepath,desired_line_number)
如果檔案很大,則應該使用顯示的迴圈,並封裝在一個函數中:
def getline(thefilepath,desired_line_number):
if desired_line_number < 1:return ''
for current_line_number,line in enumerate(open(thefilepath,'rU')):
if current_line_number == desired_line_number-1:
return line
return ''
3.何時用列表推導or產生器運算式
如果你希望使用整個列表,則使用列表推導,因為他會節省產生器帶來的系統開銷;
如果你只想用列表的一部分,那麼使用產生器吧。
4.隨機取出列表裡的元素
應該先用random.shuffle(list)把元素隨機的打亂,然後順序的取每一項即可。如果不想取到重複的,可以用list.pop(),既取出來了,又把這個元素從列表中刪除。而且內建的pop方法,非常快速。
我希望python進階。但在這之前,我還要修飾一下邊幅,上面所述的,就是在美化你的python程式。完成一個功能時,儘可能簡潔,不羅嗦,每個細節提前考慮最佳化。指令碼耦合性太強也會影響效率。
不斷補充吧。
三.文本處理
文本處理,字串處理,應該是平時用的非常多的,這裡也有最佳化技巧。
1.習慣用filter或map
fp = open('1.txt','rb')
isRegDBRoot = lambda line:line.startswith('RegDB Root')
#or
isRegDBRoot = lambda line:'Start' in line
a = filter(isRegDBRoot,fp)
結果輸出所有符合項的列表集合。