简体   繁体   English

JSON获取嵌套字典中的关键路径

[英]JSON get key path in nested dictionary

json = '{
    "app": {
        "Garden": {
            "Flowers": {
                "Red flower": "Rose",
                "White Flower": "Jasmine",
                "Yellow Flower": "Marigold"
            }
        },
        "Fruits": {
            "Yellow fruit": "Mango",
            "Green fruit": "Guava",
            "White Flower": "groovy"
        },
        "Trees": {
            "label": {
                "Yellow fruit": "Pumpkin",
                "White Flower": "Bogan"
            }
        }
    }'

Here is my json string, which keeps on changing frquently so the keys position within the dictionary is not same everytime, i need to search for a key and print it corresponding value, Since the json string changes everytime I have written an recursive function(See below) to search for key in the new json string and print the value.这是我的 json 字符串,它不断变化,因此字典中的键位置每次都不相同,我需要搜索一个键并打印相应的值,因为每次我编写递归函数时 json 字符串都会更改(参见下面)在新的 json 字符串中搜索键并打印该值。 However now the situation is we have same key multiple times with diff values, how can i get the complete path of the key so it would be easier to understand which key value it is, for example the result should be like this:但是现在的情况是我们多次使用相同的键和差异值,我怎样才能获得键的完整路径,以便更容易理解它是哪个键值,例如结果应该是这样的:

app.Garden.Flowers.white Flower = Jasmine
app.Fruits.White Flower = groovy
app.Trees.label.White Flower = Bogan

My code so far:到目前为止我的代码:

import json
with open('data.json') as data_file:    
  j = json.load(data_file)

# j=json.loads(a)


def find(element, JSON):    
  if element in JSON:
    print JSON[element].encode('utf-8')
  for key in JSON:
    if isinstance(JSON[key], dict):
      find(element, JSON[key])



find(element to search,j)

You could add a string parameter that keeps track of the current JSON path.您可以添加一个跟踪当前 JSON 路径的字符串参数。 Something like the following could work:像下面这样的东西可以工作:

def find(element, JSON, path, all_paths):    
  if element in JSON:
    path = path + element + ' = ' + JSON[element].encode('utf-8')
    print path
    all_paths.append(path)
  for key in JSON:
    if isinstance(JSON[key], dict):
      find(element, JSON[key],path + key + '.',all_paths)

You would call it like this:你可以这样称呼它:

all_paths = []
find(element_to_search,j,'',all_paths)
def getDictValueFromPath(listKeys, jsonData):
    """
    >>> mydict = {
        'a': {
            'b': {
                'c': '1'
            }
        }
    }
    >>> mykeys = ['a', 'b']
    >>> getDictValueFromPath(mykeys, mydict)
    {'c': '1'}
    """
    localData = jsonData.copy()
    for k in listKeys:
        try:
            localData = localData[k]
        except:
            return None
return localData

gist 要旨

The following code snippet will give a list of paths that are accessible in the JSON.以下代码片段将提供 JSON 中可访问的路径列表。 It's following the convention of JSON paths where [] signifies that the path is a list.它遵循 JSON 路径的约定,其中[]表示路径是一个列表。


def get_paths(source):
    paths = []
    if isinstance(source, collections.abc.MutableMapping):
        for k, v in source.items():
            if k not in paths:
                paths.append(k)
            for x in get_paths(v):
                if k + '.' + x not in paths:
                    paths.append(k + '.' + x)
    elif isinstance(source, collections.abc.Sequence) and not isinstance(source, str):
        for x in source:
            for y in get_paths(x):
                if '[].' + y not in paths:
                    paths.append('[].' + y)
    return paths

Here is a modified version of Brian's answer that supports lists and returns the result:这是 Brian 的答案的修改版本,它支持列表并返回结果:

def find(element, JSON, path='', all_paths=None):
    all_paths = [] if all_paths is None else all_paths
    if isinstance(JSON, dict):
        for key, value in JSON.items():
            find(element, value, '{}["{}"]'.format(path, key), all_paths)
    elif isinstance(JSON, list):
        for index, value in enumerate(JSON):
            find(element, value, '{}[{}]'.format(path, index), all_paths)
    else:
        if JSON == element:
            all_paths.append(path)
    return all_paths

Usage:用法:

find(JSON, element)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM