|
來自:http://blog.sina.com.cn/s/blog_48acdd250100qh93.html 需要統(tǒng)計一個文件的行數(shù). 1: 最簡單的辦法是把文件讀入一個大的列表中,然后統(tǒng)計列表的長度.如果文件的路徑是以參數(shù)的形式filepath傳遞的,那么只用一行代碼就可以完成我們的需求了: count = len(open(filepath,'rU').readlines()) 如果是非常大的文件,上面的方法可能很慢,甚至失效. 2 此時,可以使用循環(huán)來處理: count = -1 for count, line in enumerate(open(thefilepath, 'rU')): pass count += 1 3: 另外一種處理大文件比較快的方法是統(tǒng)計文件中換行符的個數(shù)'\n '(或者包含'\n'的字串,如在windows系統(tǒng)中): count = 0 thefile = open(thefilepath, 'rb') while True: buffer = thefile.read(8192*1024) if not buffer: break count += buffer.count('\n') thefile.close( ) 參數(shù)'rb'是必須的,否則在windows系統(tǒng)上,上面的代碼會非常慢. 當 外部系統(tǒng)提供統(tǒng)計行數(shù)的方法時,你可以使用它們(通過os.popen),如unix的wc - l.當然,通過自己的程序來完成會更簡單,快捷和通用.你可以假設(shè)大多數(shù)的文本文件都有合理的大小,所以把它們一次讀入內(nèi)存中處理是可行的.對于這樣的情 況,len方法返回readlines的大小是最簡單的. 加入一個文件的大小大于內(nèi)存(比如,有好幾百M那么大),那個最簡單的方法會變得難以忍受的慢,因為操作系統(tǒng)要使用虛擬內(nèi)存,并不停同過硬盤來換頁.也可能出現(xiàn)失敗的情況 ,就是虛擬內(nèi)存不夠大.一臺有256M內(nèi)存的機器,當處理一個1G或2G大小的文件的時候,仍然可能出現(xiàn)嚴重的問題.在這種情況下,使用循環(huán)處理是比較好的方式,enumerate保存了函數(shù). 第三種方法的核心思想是統(tǒng)計緩存中回車換行字符的個數(shù).這可能最不容易直接想到的方法,也是最不通用的方法,但它可能是最快的方法. 當然,在大多數(shù)情況下,性能并不是最重要的,但如果它是的話,影響性能的部分往往不是我們的直覺告訴我們的地方,所以請千萬不要相信自己的直覺, 要考評估和測量來判斷.舉例說明,對于一個中等大小的unix日志文件,比如一個18M的文本,包含了230,000行: [situ@tioni nuc]$ wc nuc 231581 2312730 18508908 nuc 使用下面的測試文件,bench.py: import time def timeo(fun, n=10): start = time.clock( ) for i in xrange(n): fun( ) stend = time.clock( ) thetime = stend-start return fun._ _name_ _, thetime import os def linecount_w( ): return int(os.popen('wc -l nuc').read( ).split( )[0]) def linecount_1( ): return len(open('nuc').readlines( )) def linecount_2( ): count = -1 for count, line in enumerate(open('nuc')): pass return count+1 def linecount_3( ): count = 0 thefile = open('nuc', 'rb') while True: buffer = thefile.read(65536) if not buffer: break count += buffer.count('\n') return count for f in linecount_w, linecount_1, linecount_2, linecount_3: print f._ _name_ _, f( ) for f in linecount_1, linecount_2, linecount_3: print "%s: %.2f"%timeo(f) 首先我調(diào)用所有的方法來讀文件,以確保不會發(fā)生異常情況(如果發(fā)生的話程序會中止),接下來,在函數(shù)timo中,我調(diào)用每種方法10次,然后看看結(jié)果,這是一個比較舊但比較穩(wěn)定的機器: [situ@tioni nuc]$ python -O bench.py linecount_w 231581 linecount_1 231581 linecount_2 231581 linecount_3 231581 linecount_1: 4.84 linecount_2: 4.54 linecount_3: 5.02 可以看出,性能上的差別不是很大,實際上,一般用戶不會在意10%左 右的性能差別.另外,最快的方法是用循環(huán)處理文件對象,而最慢的方法是統(tǒng)計換行符的個數(shù).在實際中,假如不考慮處理那些好幾百M的大文件,我總是會選中第一種最簡單的方法. 測量代碼的性能是很重要的,Python標準庫也提供了timeit來實現(xiàn)這些工作.我建議你使用timeit,而不是像我在本節(jié)做的那樣,自己寫測試代碼,我寫的代碼是好幾年前的事情了,現(xiàn)在既然有了timeit,就沒有必要再使用它了. 4: import os temp = os.popen("wc -l " + file_name).read().split()[0) int(temp) 即為 file_name的行數(shù)----------------------------------推薦用這個進行文件的個數(shù), 快額 |
|
|