2016-09-20 12 views
3

私はDeepDiffで作業しています。DeepDiffの結果を解析する

list_indexes_added = foo(added) 
list_indexes_updated = foo(updated) 

および取得するために:今すぐ

local = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 90, 'name': 'bar'}}, {3: {'age': 60, 'name': 'foobar'}}] 
online = [{1: {'age': 50, 'name': 'foo'}}, {2: {'age': 40, 'name': 'bar'}}] 
ddiff = DeepDiff(local, online) 
added, updated = ddiff['iterable_item_added'], ddiff['values_changed'] 
added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}} 
updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}} 

、私が撮りたい:だから私のような結果が持っている私は、リストを操作することができ、このように

list_indexes_added = [2] 
list_index_updated = [(1,2,'age')] 

localonline将来はonlineテーブルを更新してください。

私は正規表現で考えていますが、おそらく他のオプションがあります。

答えて

2
  • 一つの解決策は、試合の正規表現とカスタム構文解析することができます。

  • これらの文字列の正規表現の構文解析は、deepdiffの出力形式が一致している場合は後literal_evalを使用することができる別

    from ast import literal_eval 
    import re 
    
    
    def str_diff_parse(str_diff): 
        return [tuple(literal_eval(y) for y in re.findall(r"\[('?\w+'?)\]", x)) for x in str_diff] 
    
    added = {'root[2]': {3: {'age': 60, 'name': 'foobar'}}} 
    updated = {"root[1][2]['age']": {'new_value': 90, 'old_value': 40}} 
    
    list_indexes_added = str_diff_parse(added) 
    list_indexes_updated = str_diff_parse(updated) 
    
    print(list_indexes_added) 
    print(list_indexes_updated) 
    # prints 
    #[(2,)] 
    #[(1, 2, 'age')] 
    

デモhttp://ideone.com/3MhTky

  • dictdifferを勧めますモジュールでは、diffを消耗品python diffオブジェクトとして返します。更新されたものを取得するために元の辞書にパッチを適用するか、またはその逆を行う。
1

だから、私はこのようなものでいいと思う:

import re 

def foo(diff): 
modded = [] 

for key in diff.keys(): 
    m = re.search('\[(.+)\]', key) 
    modded.append(tuple(m.group(1).split(']['))) 

return modded 

これは、各キーを読んであげる、唯一のインデックス(数値または文字列かどうか)を抽出し、文字列をスライス。あなたの望む出力はタプルを示しているので、インデックスのシーケンスを1に戻し、インデックスセットのリスト全体を返します(diffは複数あるかもしれません)。

これは、1行のリスト内包にダウンgolfedすることができます。

import re 

def foo(diff): 
    return [tuple(re.search('\[(.+)\]', key).group(1).split('][')) for key in diff.keys()] 
1

これは私がやったことです:だから

def getFromSquareBrackets(s): 
    return re.findall(r"\['?([A-Za-z0-9_]+)'?\]", s) 

def auxparse(e): 
    try: 
     e = int(e) 
    except: 
     pass 
    return e 

def castInts(l): 
    return list((map(auxparse, l))) 

def parseRoots(dics): 
    """ 
     Returns pos id for list. 
     Because we have formmatted [{id:{dic}}, {id:{dic}}] 
    """ 
    values = [] 
    for d in dics: 
     values.append(castInts(getFromSquareBrackets(d))) 
    return values 

parseRoots({"root[1][2]['age']": {'new_value': 90, 'old_value': 40}}) 
[[1, 2, 'age']] 

はたぶん誰かがそれを改善することができます。

関連する問題