2016-03-07 88 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)”如果有更多的路径需要探索,你会在这里错过它们。如果您删除关键字返回代码将采取不同的行动,我认为你可以从那里解决它。

祝你好运!

相关问题