首页 > 解决方案 > 使用 Python 通过嵌套 json 文件中的值获取键

问题描述

我想从程序中提取值为 Wally 的键路径

arr = []
sub_arr = []
def extract(obj, sub_arr, val):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, (dict, list)):    
                sub_arr.append(k)            
                extract(v, sub_arr, val)
            elif v == val:
                sub_arr.append(k)
                arr.append(sub_arr)
                sub_arr = []
    elif isinstance(obj, list):
        for item in obj:
            if isinstance(item, (dict, list)):
                sub_arr.append(obj.index(item))
                extract(item, sub_arr, val)      
            elif item == val:
                sub_arr.append(obj.index(item))
                arr.append(sub_arr)    
                sub_arr = []
    return arr

obj =  {
        "News": [
            {
                "Title": "NewsA",
                "Tags": ["Gossiping"],
                "Date": "2021/06/26",
                "Detail": {
                    "Author": "Wally",
                    "Content": "Hello World"
                }
            },
            {
                "Title": "NewsB",
                "Tags": ["Social", "Wally"],
                "Date": "2021/06/27",
                "Detail": {
                    "Author": "Andy",
                    "Content": "Taiwan NO.1"
                }
            }
        ]
    }
print(extract(obj, sub_arr, "Wally"))

这是迄今为止我得到的最好的结果

[
  ['News', 0, 'Tags', 'Detail', 'Author', 1, 'Tags', 1, 'Detail']
, ['News', 0, 'Tags', 'Detail', 'Author', 1, 'Tags', 1, 'Detail']
]

我想要的价值是这样的

[['News', 0, 'Detail', 'Author'], ['News', 1, 'Tags', 1]]

很卡在这里。有什么我错过的吗?将不胜感激

标签: pythonjsonnested

解决方案


列表是可变的,并且会在您的提取函数的每次迭代中传递。在您的情况下, sub_arr 被无限附加,这解释了您得到的答案。因此,以这种方式使用列表时请务必小心。

一种解决方案是为 extract 的每个函数调用创建一个新列表,例如:

arr = []
sub_arr = []
def extract(obj, sub_arr, val):
    if isinstance(obj, dict):
        for k, v in obj.items():
            found_arr = [*sub_arr, k]
            if isinstance(v, (dict, list)):
                extract(v, found_arr, val)
            elif v == val:
                arr.append(found_arr)
    elif isinstance(obj, list):
        for item in obj:
            found_arr = [*sub_arr, obj.index(item)]
            if isinstance(item, (dict, list)):
                extract(item, found_arr, val)
            elif item == val:
                arr.append(found_arr)
    return arr

obj = {
        "News": [
            {
                "Title": "NewsA",
                "Tags": ["Gossiping"],
                "Date": "2021/06/26",
                "Detail": {
                    "Author": "Wally",
                    "Content": "Hello World"
                }
            },
            {
                "Title": "NewsB",
                "Tags": ["Social", "Wally"],
                "Date": "2021/06/27",
                "Detail": {
                    "Author": "Andy",
                    "Content": "Taiwan NO.1"
                }
            }
        ]
    }
print(extract(obj, sub_arr, "Wally"))

这会产生所需的答案:

[['News', 0, 'Detail', 'Author'], ['News', 1, 'Tags', 1]]

推荐阅读