2014-01-25 103 views
2

我需要幫助,試圖使用difflib來比較兩個字典。我的程序需要2個json文件,將它們轉換爲python字典。然後我想在這兩個詞典上使用difflib來顯示兩者之間的差異。difflib來比較兩個python字典

什麼是使用difflib來解決這個問題的正確方法?

#!/usr/bin/env python2 

import json 
import collections 
import difflib 
import pprint 

def get_json(): 
    file_name = raw_input("Enter name of JSON File: ") 
    with open(file_name) as json_file: 
     json_data = json.load(json_file) 
     return json_data 

def convert(data): 
    if isinstance(data, basestring): 
     return str(data) 
    elif isinstance(data, collections.Mapping): 
     return dict(map(convert, data.iteritems())) 
    elif isinstance(data, collections.Iterable): 
     return type(data)(map(convert, data)) 
    else: 
     return data 

def main(): 
    json1 = get_json() 
    json2 = get_json() 
    json1_dict = convert(json1) 
    json2_dict = convert(json2) 
    result = list(difflib.Differ.compare(json1_dict, json2_dict)) 
    pprint.pprint(result) 

if __name__ == "__main__": 
    main() 

JSON例如:

{ 
    "glossary": { 
     "title": "example glossary", 
     "GlossDiv": { 
      "title": "S", 
      "GlossList": { 
       "GlossEntry": { 
        "ID": "SGML", 
        "SortAs": "SGML", 
        "GlossTerm": "Standard Generalized Markup Language", 
        "Acronym": "SGML", 
        "Abbrev": "ISO 8879:1986", 
        "GlossDef": { 
         "para": "A meta-markup language, used to create markup languages such as DocBook.", 
         "GlossSeeAlso": [ 
          "GML", 
          "XML" 
         ] 
        }, 
        "GlossSee": "markup" 
       } 
      } 
     } 
    } 
} 

,並在第二文件中更改ID,以 「1234」 的值

我想比較這兩個和像get和輸出:

{ 
    "glossary": { 
     "title": "example glossary", 
     "GlossDiv": { 
      "title": "S", 
      "GlossList": { 
       "GlossEntry": { 
-     "ID": "SGML", 
+     "ID": "1234", 
        "SortAs": "SGML", 
        "GlossTerm": "Standard Generalized Markup Language", 
        "Acronym": "SGML", 
        "Abbrev": "ISO 8879:1986", 
        "GlossDef": { 
         "para": "A meta-markup language, used to create markup languages such as DocBook.", 
         "GlossSeeAlso": [ 
          "GML", 
          "XML" 
         ] 
        }, 
        "GlossSee": "markup" 
       } 
      } 
     } 
    } 
} 
+0

'Differ.compare'是一種實例方法。除了擺脫unicode字符串之外,你的'convert'函數有什麼用處嗎?無論如何,'difflib'適用於線序,不適用於字典等任意對象。你的json文件有什麼樣的內容?你期望你的程序的輸出是什麼樣的? – Blckknght

+0

我不認爲這是difflib的用途;這是爲了產生文本文件之間的差異。 你的JSON文件的結構是什麼?他們只有2級(左右)深,還是需要遞歸解決方案? – dstromberg

+0

convert函數只是爲了擺脫unicode,有沒有更好的方法來做到這一點?我將用json文件的示例和預期的輸出來編輯問題 – user3230554

回答

1

這裏有幾個問題。首先,您嘗試使用方法difflib.Differ.compare,但您將其稱爲普通函數 - 實際上並沒有創建對象的difflib.Differ

其次,這個compare方法期望您對字符串序列(對於比較的兩個事物中的每一個)進行操作。你的convert函數有時會返回字符串,有時候是字典,有時候還會有其他的東西......一般來說,你沒有得到字符串序列。

得到你想要的東西的自然方法是隻比較實際的JSON數據,因爲這是一個字符串。但是,有兩個問題有:

  • 你想要的字符串(行由行),而不是一個字符串與整個JSON文件的序列,但是這是微不足道的 - 只是把它分解成與行字符串.splitlines方法。

  • 您的輸入可能在您要忽略的空白中存在差異。解決這個問題的簡單方法是在load將每個JSON文檔放入一個對象後,用dumps重新創建一個字符串。我們的想法是,對於您正在比較的兩個文檔,您將使用相同的空白設置轉儲。您需要閱讀文檔並確定要使用的設置。