difflib比较两个python词典

时间:2014-01-25 02:43:18

标签: python dictionary

我需要帮助尝试使用difflib来比较两个dicts。我的程序需要2个json文件,将它们转换为python dicts。然后我想在两个dicts上使用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"
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

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

其次,这个compare方法希望你对一系列字符串进行操作(对于被比较的两个事物中的每一个)。您的convert函数有时会返回字符串,有时会返回字符串,有时会返回其他内容......通常情况下,您不会返回字符串序列。

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

  • 你想要一个字符串序列(逐行)而不是整个JSON文档的单个字符串,但这很简单 - 只需用字符串.splitlines方法将其拆分成行。

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