2016-01-13 28 views
2

我比較一個json對象的所有元素是否在另一個json中。 因爲我抓住了小一層的所有鑰匙,並檢查它們是否在大的一個,如果他們是相同的。進入更深層次,我稱之爲給它包含更深層的元素的函數。 (在這個函數中,現在我使用關鍵「結果」檢測更深的層,但是我未來會將其更改爲可變關鍵字 我的問題是我無法調用遞歸函數,它是「字符串索引必須是整數試圖調用該函數的功能時,不是Unicode」腳本json在python中與另一個json進行遞歸比較

def compareJson(example_json_s, target_json_s): 
    #parsed_json 
    example_json = example_json_s 
    target_json = target_json_s 
    p = 0 
    keys = [] 
    for key in example_json.keys(): 
     keys.insert(p, key) 
     p = p + 1 

    passed = 0; 
    for x in keys: 
     print "Keys" 
     if x != "results": 
      if not x in target_json or x not in example_json.keys() and not example_json[x] == target_json[x]: 
       passed = 1 
     else: 
      print """###inhabits "results " going one layer deeper""" 
     compareJson(example_json[key], target_json[key]) 
    return passed 

和一些示例JSON對象:

{ 
    "results": { 
     "clock": true, 
     "update": false, 
     "autoreg": false 
    } 
} 

{ 
    "id": "1523", 
    "dlid": "009029", 
    "serial": "1017030022", 
    "statuscode": 128, 
    "results": { 
     "event": true, 
     "counter": true, 
     "clock": true, 
     "eqep": true, 
     "usb": false, 
     "modem": true, 
     "sim": true, 
     "pin": true, 
     "encrypt": false, 
     "upload": true, 
     "update": true, 
     "autoreg": true 
    }, 
    "ok": false, 
    "confirmed": false 
} 

和錯誤代碼在這裏:

Traceback (most recent call last): 
    File "/home/philip/Desktop/empfang_test.py", line 199, in <module> 
    empfange() #Programm wartet in einer Endlosschleife auf eingehende Nachrichten. 
    File "/home/philip/Desktop/empfang_test.py", line 193, in empfange 
    checkvalue=compareJson(json.loads(config[1][1]),parsed_json_dummy) 
    File "/home/philip/Desktop/empfang_test.py", line 183, in compareJson 
    compareJson(example_json[key],target_json[key]) 
TypeError: string indices must be integers, not str 
+0

你能修復縮進,並添加完整的錯誤消息啓動時? – M4rtini

+0

期望的輸出是什麼?真/假或列表(或字典)哪些字段存在? – Pynchia

+0

夾具https://pythonhosted.org/testfixtures/comparing.html提供字典比較呢? –

回答

0

我認爲下面的代碼應該做的伎倆:

def compareJson(example_json_s, target_json_s): 
example_json = json.loads(example_json_s) 
target_json = json.loads(target_json_s) 
return compareParsedJson(example_json, target_json) 

def compareParsedJson(example_json, target_json): 
for x in example_json: 
    if type(example_json[x]) is not dict: 
    if not x in target_json or not example_json[x] == target_json[x]: 
     return False 
    else: 
    if x not in target_json or not compareParsedJson(example_json[x], target_json[x]): 
     return False 

return True 

在第一個函數中,我們分析了完整的JSON對象(包括遞歸部分)。第二個分析它們。

我對您的代碼進行了一些更改。

  • 沒有必要先獲取密鑰列表,您可以重複執行example_json.keys()。另外,我會用你的例子中的keys.append(key)代替它。
  • 該函數檢查嵌套的json對象的類型現在是否爲dict(它已被解析)。如果沒有,那麼它會比較它們,如果是的話,那麼它會進入下一個。您可能想爲列表添加類似的子句。
  • 只要JSON的一部分不相同,該函數就會返回False

編輯:爲了響應您發佈的錯誤代碼,我想你可能沒有正確解析json。我將你的評論#parsed_json表示爲你的意思,但我認爲你錯過了上述代碼示例中包含的json.loads方法調用..?

+0

非常歡迎。感謝您接受答案。 – MrHug

+1

在旁註中,當你想要迭代字典時,避免使用'dict.keys()'。簡單地刪除'.keys()'來得到'for k in dict:'。參考:http://stackoverflow.com/questions/4730993/python-key-in-dict-keys-performance-for-large-dictionaries – jatinderjit

+0

好點,謝謝:) – MrHug

0

這裏是我的解決方案

def contained(a, b): 
    """ checks if dictionary a is fully contained in b """ 
    if not isinstance(a, dict): 
     return a == b 
    else: 
     return all(contained(v, b.get(k)) for k, v in a.items()) 

print(contained(d1, d2)) 

它,您的輸入提供了False

d1 = { 
     "results": { 
        "clock": True, 
        "update": True, 
        "autoreg": True 
       } 
    } 

True

d1 = { 
    "results": { 
     "clock": True, 
     "update": True, 
     "autoreg": True, 
     "qqq": True 
    } 
} 

即一個密鑰從目標中丟失(例如,qqq),它給False

當然你也可以用

contained(json.loads(example_json_s), json.loads(target_json_s)) 

把它從一個JSON字符串

+0

我認爲,如果有'k'這樣那'k不在b'它應該返回'False'? – MrHug

+0

@MrHug是的,修復。謝謝 – Pynchia

相關問題