簡體   English   中英

使用 python 查找帶有密鑰的嵌套 Json 路徑

[英]Find Nested Json Path with key using python

我正在嘗試查找特定密鑰的所有完整路徑。 我嘗試使用遞歸,我可以獲取值,但我無法使用我的代碼跟蹤路徑。 任何幫助肯定對我有用。

輸入:

{
  "id": ["0001"],
  "type": "donut",
  "name": "Cake",
  "ppu": 0.55,
  "batters": {
    "batter": {
      "id": ["1001"],
      "type": "Regular"
    }
  },
  "topping": [
    {
      "id": ["5001"],
      "type": "None"
    },
    {
      "id": ["5002"],
      "type": "Glazed"
    }
  ]
}

預期 Output:

[
    {"id":["0001"]},
    {"batters.batter.id":["1001"]},
    {"topping[0].id":["5001"]},
    {"topping[0].id":["5002"]}
]

以下代碼是我用來獲取值的,但它對我沒有幫助。

def json_extract(obj, key):
    """Recursively fetch values from nested JSON."""
    arr = []

    def extract(obj, arr, key):

        """Recursively search for values of key in JSON tree."""
        if isinstance(obj, dict):
            for k, v in obj.items():
                if isinstance(v, (dict)):
                    extract(v, arr, key)
                elif k == key:
                    arr.append(v)
        elif isinstance(obj, list):
            for item in obj:
                extract(item, arr, key)
        return arr

    values = extract(obj, arr, key)
    return values

您可以使用此代碼來實現相同的目標(盡管未優化)。

import json
# Opening JSON file
f = open('del.json')
data = json.load(f)
arr = []
def json_extract(obj, key):
    def dfs(obj, key, prefix):
        for k, v in obj.items():
            if(isinstance(v, dict)):
                if(k == key):
                    arr.append((prefix+"."+k if prefix else k, v))
                else:
                    dfs(v, key, prefix + "." + k if prefix else k)
            elif(isinstance(v, list)):
                if(k == key):
                    arr.append((prefix+"."+k if prefix else k, v))
                else:
                    for i, val in enumerate(v):
                        dfs(val, key, prefix + k + f"[{i}]")
  
    dfs(obj, key, "")
    
json_extract(data, "id")
for i in arr:
    print(i)

感謝您提供解決方案Olvin Right

def get_paths(source, key="", target = None):
    if isinstance(source, dict):
        for source_key, source_value in source.items():
            tmp_key = f"{key}.{source_key}" if key else source_key
            if source_key == target:
                yield tmp_key, source_value, source.get('_type')
            else:
                yield from get_paths(source_value, tmp_key, target)
    elif isinstance(source, (list, tuple, set, frozenset)):
        for index, value in enumerate(source):
            yield from get_paths(value, f"{key}[{index}]", target)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM