2011-03-22 69 views
0

我有兩個文件,稱爲源和目標。我比較源中的每個元素以檢查它是否也存在於目標中。如果它不存在於目標中,我將它打印出來(最終目標是有0的差異)。這是我寫的代碼。比較Python中的文件內容

 
def finddefaulters(source,target): 
    f = open(source,'r') 
    g = open(target,'r') 

    reference = f.readlines() 
    done = g.readlines() 
    for i in reference: 
    if i not in done: 
     print i, 

我需要

  1. 幫助,這將如何代碼在額定1-10
  2. 規模我怎樣才能使它更好,最佳,如果文件大小是巨大的。

另一個問題 - 當我將所有行讀作列表元素時,它們被解釋爲'element \ n' - 所以爲了正確比較,我必須在每個文件的末尾添加一個換行符。有沒有辦法去掉換行符,所以我不必在文件末尾添加換行符。我試過rstrip。但它沒有奏效。 在此先感謝。

+0

'done = g.readlines()'創建一個列表。 '如果我沒有完成'在列表中搜索。多次。看看'set()'。 – eumiro 2011-03-22 14:30:29

+4

您似乎在重新創建[diff](http://docs.python.org/library/difflib.html) – 2011-03-22 14:31:25

+0

除了其他所有內容之外,「f」和「g」對於您的變量來說都是可怕的名稱。稱他們是明智的。 「我」也可以改進。 – 2011-03-22 14:32:54

回答

2

關於效率:如果雙擊兩個列表的大小顯示您的方法具有O(m*n)asymptotic runtime complexity其中mnreferencedone,即元件的數量,該算法將運行4次更長(時間固定的常數,與理論計算機科學家無關)。如果mn非常大,則可能需要選擇更快的算法,例如,首先使用.sort()(運行時複雜度:O(n * log(n)))對兩個列表進行排序,然後再遍歷列表一次(運行時複雜度:O(n))。該算法的運行時間複雜度最差爲O(n * log(n)),這已經是一個很大的改進。但是,爲了提高效率,您交易代碼的可讀性和簡單性,所以我只會建議您在絕對必要的情況下執行此操作。

關於編碼風格:您不需要.close()您應該使用的文件句柄。而不是打開和關閉文件句柄,你可以使用python的with language construct。另外,如果你喜歡的功能的風格,你可以通過一個表的表達式替換for循環:

for i in reference: 
    if i not in done: 
     print i, 

就變成了:

items = [i.strip() for i in reference if i not in done] 
print ' '.join(items) 

不過,這樣你將不會看到,而列表中的任何進展正在組成。

由於joaquin已經提到,您可以直接循環使用f而不是f.readlines(),因爲文件句柄支持iterator protocol

2

一些想法:

1)使用[with]安全地打開文件:

with open(source) as f: 
    ............. 

with語句用於包裝與上下文管理器中定義的方法 的 執行塊。這 允許共同嘗試...除了...終於 使用模式被封裝爲 方便重用。

2),你可以在一個文件,而不是使用readlines方法的行迭代:

for line in f: 
    .......... 

3)雖然這一小段它可能是不夠的,試圖爲你的變量使用更翔實的名字。不建議使用單字母名稱。

4)如果您想獲得python lib的利潤,請嘗試difflib模塊中的函數。例如:

make_file(fromlines, tolines[, fromdesc][, todesc][, context][, numlines]) 

比較fromlines和tolines(列表串 ),並返回一個字符串,它 是含有由線差異 與線間和分子內一個 表,示出線路一個完整的HTML文件突出顯示行更改 。

+0

您可以提供帶有關鍵字文檔的鏈接,或者說明它的作用。 – 2011-03-22 14:35:00