2016-03-07 86 views
0

我試圖從邏輯上遍歷Python中的JSON並返回等於值的任何字符串值的路徑。我試圖遞歸遍歷,但如果多個元素的比較匹配,它只首先返回他:Python - 與字符串匹配的所有JSON元素的返回路徑

test_json = { 
    "a": { 
     "b": { 
      "c": { 
       "d": "foo" 
      } 
     } 
    }, 
    "1": { 
     "2": { 
      "3": "bar" 
     } 
    }, 
    "a1" : "foo" 
} 

def searchDict(d, path): 
    for k,v in d.iteritems(): 
     if isinstance(v, dict): 
      path.append(k) 
      return searchDict(v, path) 
     else: 
      if v == "foo": 
       path.append(k) 
       path.append(v) 
       return path 

print searchDict(test_json, []) 

我想這不得不返回類似的能力:

a -> b -> c -> d -> foo 
a1 -> foo 

但相反,它只是遍歷第一個子字典:

['a', 'b', 'c', 'd', 'foo'] 

這可能比我做得更容易,只是在邏輯上解決它有困難。有任何想法嗎?

回答

1

這是一個很好的問題。你實際上距離自己解決問題只有兩步之遙。

  1. 附加到路徑變量將導致相同的變量將用於所有的遞歸調用。使用路徑+ [k]將解決這個問題。如果很難嘗試使用代碼並在searchdict函數的開頭打印出路徑
  2. 您正確使用for循環遍歷json文件。但是,你也在forcycle中返回,這會阻止它,並且其他可能性不會被探索。打印結果,將其添加到結果字段或使用python的生成器來獲得結果

查看我修改的工作代碼。試着對你的代碼做一點改動,這樣很容易理解。

test_json = { 
    "a": { 
     "b": { 
      "c": { 
       "d": "foo" 
      } 
     } 
    }, 
    "1": { 
     "2": { 
      "3": "bar" 
     } 
    }, 
    "a1" : "foo" 
} 

def searchDict(d, path): 
    for k,v in d.iteritems(): 
     if isinstance(v, dict): 
      searchDict(v, path + [k]) 
     else: 
      if v == "foo": 
       print(path + [k] + [v]) 


searchDict(test_json, []) 
+0

啊,是的。我知道這很簡單。放棄回報是有道理的。謝謝! – ev0lution37

+0

幹得好;-)最好的解決方案是使用python生成器和yield。如果你想成爲專業人士,請閱讀它;-) –

1

一對夫婦的意見,也許提示:

  1. 你希望你的算法打印所有的路徑,但如果只留一個列表。所以你要把所有的路徑添加到同一個數據結構中。聽起來更像是你想要的清單列表,也可能是你傳遞的額外列表變量。你的選擇
  2. 你在一個稍微陌生的地方打破循環「return searchDict(v,path)」如果有更多的路徑需要探索,你會在這裏錯過它們。如果您刪除關鍵字返回代碼將採取不同的行動,我認爲你可以從那裏解決它。

祝你好運!

相關問題