Skip to main content
 首页 » 编程设计

python之difflib 比较两个 python 字典

2025年05月04日8kevingrace

我需要帮助尝试使用 difflib 比较两个字典。我的程序需要 2 个 json 文件,将它们转换为 python 字典。然后我想在两个字典上使用 difflib 来显示两者之间的差异。

使用 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”

我想比较两者并得到和输出类似的东西:

{ 
    "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" 
                } 
            } 
        } 
    } 
} 

请您参考如下方法:

这里有一些问题。首先,您尝试使用方法 difflib.Differ.compare ,但您将其称为普通函数 - 您实际上并未创建 difflib.Differ 对象。

二、这个compare方法期望您对一系列字符串进行操作(对于要比较的两个事物中的每一个)。你的convert函数有时会返回字符串,有时会返回字典,有时会返回其他内容……一般来说,您不会返回字符串序列。

获得所需内容的自然方法是只比较实际的 JSON 数据,因为那是一个字符串。但是,这里有两个问题:

  • 您需要一系列字符串(逐行)而不是包含整个 JSON 文档的单个字符串,但这很简单 - 只需将其分成包含字符串 .splitlines 的行即可方法。

  • 您的输入可能有您想要忽略的空格差异。解决这个问题的简单方法是,在 load 之后将每个 JSON 文档转换为一个对象,用 dumps 为它重新创建一个字符串.这个想法是,对于您正在比较的两个文档,您将使用相同的空白设置转储。您需要阅读文档并决定要使用的设置。