2

非常に複雑で、大きな xml ファイルを python 辞書に変換することによって作成された 2 つの辞書オブジェクトがあります。

辞書の深さがわからず、比較して次の出力が必要なだけです...

例 私の辞書はこのようなものです

d1 = {"great grand father":
         {"name":"John",
          "grand father":
             {"name":"Tom",
              "father":
                 {"name":"Andy",
                  "Me":
                     {"name":"Mike",
                      "son": 
                         {"name":"Tom"}
                     }
                 }
             }
         }
     }

d2 も同様ですが、フィールドのいずれかが欠落しているか、以下のように変更されている可能性があります

d2 = {"great grand father":
         {"name":"John",
          "grand father":
             {"name":"Tom",
              "father":
                 {"name":"Andy",
                  "Me":
                     {"name":"Tonny",
                      "son": 
                         {"name":"Tom"}
                     }
                 }
             }
         }
     }

辞書の比較により、次のような結果が得られるはずです-

Expected Key/Val : Me->name/"Mike" 
Actual Key/Val : Me->name/"Tonny"

キー「name」がd2の「Me」に存在しない場合、次の出力が得られるはずです

Expected Key/Val : Me->name/"Mike" 
Actual Key/Val : Me->name/NOT_FOUND

繰り返しますが、辞書の深さは可変または動的に生成できます。ここにある 2 つの辞書は例として示されています...

SOで見たすべての辞書比較の質問とその回答は、固定深度の辞書に関連しています.....

4

2 に答える 2

2

幸運なことに、私はこれを私が働いていたプロジェクトの一環として行いました。

次のような再帰関数が必要です。

def checkDifferences(dict_a,dict_b,differences=[])

最初に、どちらにも存在しないキーを確認できます。例えば

Expected Name/Tom Actual None

次に、値のタイプを比較します。つまり、値が辞書かリストかなどを確認します。

そうであれば、値を dict_a/b として使用して関数を再帰的に呼び出すことができます。再帰的に呼び出すときは、差分配列を渡します。

値の型がリストで、リストに辞書が含まれている可能性がある場合は、リストを辞書に変換し、変換された辞書で関数を呼び出す必要があります。

申し訳ありませんが、これ以上お力になれませんが、ソース コードにアクセスできなくなりました。うまくいけば、これで十分です。

于 2013-06-27T12:50:29.380 に答える
1

ここで、任意の 2 つの辞書を比較する方法を見つけました -

私はあらゆる深さのさまざまな辞書を試して、私のために働きました。コードはそれほどモジュール化されていませんが、参照用です-

import pprint

pp = pprint.PrettyPrinter(indent=4)

dict1 = { 'Person' : { 'Male' : {'Boys' : {'Roger' : {'age' : 20},
                                           'Rafa' : {'age' : 25}
                                          }
                                },
                       'Female' : { 'Girls' : {'Serena' : {'age' : 23},
                                               'Maria' : {'age' : 15}
                                              }
                                  }

                     },
          'Animal' : { 'Huge' : {'Elephant' : {'color' : 'black' }
                                }
                     }
        }
'''
dict2 = { 'Person' : { 'Male' : {'Boys' : {'Roger' : {'age' : 20}
                                          }
                                },
                       'Female' : { 'Girls' : {'Serena' : {'age' : 23},
                                               'Maria' : {'age' : 1}
                                              }
                                  }
                     }
        }

dict2 = { 'Person' : { 'Male' : {'Boys' : {'Roger' : {'age' : 20},
                                           'Rafa' : {'age' : 2}
                                          }
                                }
                     }
        }
'''

dict2 = { 'Person' : { 'Male' : {'Boys' : {'Roger' : {'age' : 2}}},
                       'Female' : 'Serena'}
        }


key_list = []
err_list = {}
def comp(exp,act):
    for key in exp:
        key_list.append(key)
        exp_val = exp[key]
        try:
            act_val = act[key]
            is_dict_exp = isinstance(exp_val,__builtins__.dict)
            is_dict_act = isinstance(act_val,__builtins__.dict)

            if is_dict_exp == is_dict_act == True:
                comp(exp_val,act_val)
            elif is_dict_exp == is_dict_act == False:
                if not exp_val == act_val:
                    temp = {"Exp" : exp_val,"Act" : act_val}
                    err_key = "-->".join(key_list)
                    if err_list.has_key(key):
                        err_list[err_key].update(temp)
                    else:
                        err_list.update({err_key : temp})
            else:
                temp = {"Exp" : exp_val, "Act" : act_val}
                err_key = "-->".join(key_list)
                if err_list.has_key(key):
                    err_list[err_key].update(temp)
                else:
                    err_list.update({err_key : temp})

        except KeyError:
            temp = {"Exp" : exp_val,"Act" : "NOT_FOUND"}
            err_key = "-->".join(key_list)
            if err_list.has_key(key):
                err_list[err_key].update(temp)
            else:
                err_list.update({err_key : temp})
        key_list.pop()

comp(dict1,dict2)

pp.pprint(err_list)

ここに私のコードの出力があります -

{   'Animal': {   'Act': 'NOT_FOUND',
                  'Exp': {   'Huge': {   'Elephant': {   'color': 'black'}}}},
    'Person-->Female': {   'Act': 'Serena',
                           'Exp': {   'Girls': {   'Maria': {   'age': 15},
                                                   'Serena': {   'age': 23}}}},
    'Person-->Male-->Boys-->Rafa': {   'Act': 'NOT_FOUND', 'Exp': {   'age': 25}},
    'Person-->Male-->Boys-->Roger-->age': {   'Act': 2, 'Exp': 20}
}

コメント付きのコードで指定された他の辞書を試すこともできます..

もう1つ-キーは予想される辞書でチェックされ、実際の辞書と一致します。辞書を交互に渡すと、逆のマッチングも可能です...

comp(dict2,dict1)
于 2013-07-03T14:13:34.613 に答える