如何从嵌套的JSON文件中提取JSON?

yzuktlbb  于 2023-11-20  发布在  其他
关注(0)|答案(4)|浏览(180)

我正在调用一个API,并得到如下所示的响应。

{
    "status": 200,
    "errmsg": "OK",
    "data": {
        "total": 12,
        "items": [{
                "id": 11,
                "name": "BBC",
                "priority": 4,
                "levelStr": "All",
                "escalatingChainId": 3,
                "escalatingChain": {
                    "inAlerting": false,
                    "throttlingAlerts": 20,
                    "enableThrottling": true,
                    "name": "Example123",
                    "destination": [],
                    "description": "",
                    "ccdestination": [],
                    "id": 3,
                    "throttlingPeriod": 10
                }
            },
            {
                "id": 21,
                "name": "CNBC",
                "priority": 4,
                "levelStr": "All",
                "escalatingChainId": 3,
                "escalatingChain": {
                    "inAlerting": false,
                    "throttlingAlerts": 20,
                    "enableThrottling": true,
                    "name": "Example456",
                    "destination": [],
                    "description": "",
                    "ccdestination": [],
                    "id": 3,
                    "throttlingPeriod": 10
                }
            }
        ]
    }
}

字符串
我需要清理一下这个JSON,并生成一个简单的JSON,如下所示,其中escalatingChainNameescalatingChain列表中的name,以便我可以将其写入CSV文件。

{
    "items": [{
            "id": 11,
            "name": "BBC",
            "priority": 4,
            "levelStr": "All",
            "escalatingChainId": 3,
            "escalatingChainName": "Example123"
        },
        {
            "id": 21,
            "name": "CNBC",
            "priority": 4,
            "levelStr": "All",
            "escalatingChainId": 3,
            "escalatingChainName": "Example456"
        }
    ]
}


有没有一个JSON函数可以用来只复制必要的键值或嵌套键值到一个新的JSON对象?
使用下面的代码,我可以得到详细信息列表。

json_response = response.json()
items = json_response['data']
details = items['items']


我可以打印单个列表项,

for x in details:
    print(x)


我如何从这里只提取必要的字段,如id,name,priority和escalatingchain中的name来创建一个新的列表或JSON?

i34xakig

i34xakig1#

没有现成的函数可以满足你的要求,所以你需要写一个函数。幸运的是,在这种情况下这并不太难--基本上你只需要从现有的数据中提取出你想要的数据片段来创建一个新的项目列表。

import json

json_response = """\
    {
        "status": 200,
        "errmsg": "OK",
        "data": {
            "total": 12,
            "items": [{
                    "id": 11,
                    "name": "BBC",
                    "priority": 4,
                    "levelStr": "All",
                    "escalatingChainId": 3,
                    "escalatingChain": {
                        "inAlerting": false,
                        "throttlingAlerts": 20,
                        "enableThrottling": true,
                        "name": "Example123",
                        "destination": [],
                        "description": "",
                        "ccdestination": [],
                        "id": 3,
                        "throttlingPeriod": 10
                    }
                },
                {
                    "id": 21,
                    "name": "CNBC",
                    "priority": 4,
                    "levelStr": "All",
                    "escalatingChainId": 3,
                    "escalatingChain": {
                        "inAlerting": false,
                        "throttlingAlerts": 20,
                        "enableThrottling": true,
                        "name": "Example456",
                        "destination": [],
                        "description": "",
                        "ccdestination": [],
                        "id": 3,
                        "throttlingPeriod": 10
                    }
                }
            ]
        }
    }
"""

response = json.loads(json_response)

cleaned = []
for item in response['data']['items']:
    cleaned.append({'id': item['id'],
                    'name': item['name'],
                    'priority': item['priority'],
                    'levelStr': item['levelStr'],
                    'escalatingChainId': item['escalatingChainId'],
                    'escalatingChainName': item['escalatingChain']['name']})

print('cleaned:')
print(json.dumps(cleaned, indent=4))

字符串

jgovgodb

jgovgodb2#

您可以尝试:

data = {
    "status": 200,
    "errmsg": "OK",
    "data": {
        "total": 12,
        "items": [{
                "id": 11,
                "name": "BBC",
                "priority": 4,
                "levelStr": "All",
                "escalatingChainId": 3,
                "escalatingChain": {
                    "inAlerting": False,
                    "throttlingAlerts": 20,
                    "enableThrottling": True,
                    "name": "Example123",
                    "destination": [],
                    "description": "",
                    "ccdestination": [],
                    "id": 3,
                    "throttlingPeriod": 10
                }
            },
            {
                "id": 21,
                "name": "CNBC",
                "priority": 4,
                "levelStr": "All",
                "escalatingChainId": 3,
                "escalatingChain": {
                    "inAlerting": False,
                    "throttlingAlerts": 20,
                    "enableThrottling": True,
                    "name": "Example456",
                    "destination": [],
                    "description": "",
                    "ccdestination": [],
                    "id": 3,
                    "throttlingPeriod": 10
                }
            }
        ]
    }
}

for single_item in data["data"]["items"]:
    print(single_item["id"])
    print(single_item["name"])
    print(single_item["priority"])
    print(single_item["levelStr"])
    print(single_item["escalatingChain"]["inAlerting"])
    # and so on

字符串

knpiaxh1

knpiaxh13#

有两种方法可以实现这一点,这取决于你是使用python列表和字典理解来处理变量还是.json文件:
1.其中字典(嵌套)类型的数据变量已经定义:

# keys you want
to_keep = ['id', 'name', 'priority', 'levelStr', 'escalatingChainId',
           'escalatingChainName']
new_data = [{k:v for k,v in low_dict.items() if k in to_keep}
            for low_dict in data['data']['items']]
# where item is dictionary at lowest level
escalations = [{v+'Name':k[v]['name']} for k in data['data']['items']
                                        for v in k if type(k[v])==dict]
# merge both lists of python dictionaries to produce flattened list of dictionaries
new_data = [{**new,**escl} for new,escl in zip(new_data,escalations)]

字符串
1.或者(由于您引用了json包)如果您将响应保存为.json文件:

import json

with open('response.json', 'r') as handl:
    data = json.load(handl)
to_keep = ['id', 'name', 'priority', 'levelStr', 'escalatingChainId',
           'escalatingChainName']
new_data = [{k:v for k,v in low_dict.items() if k in to_keep}
                     for low_dict in data['data']['items']]
escalations = [{v+'Name':k[v]['name']} for k in data['data']['items']
                                         for v in k if type(k[v])==dict]
new_data = [{**new,**escl} for new,escl in zip(new_data,escalations)]


两者都产生输出:

[{'id': 11,
  'name': 'BBC',
  'priority': 4,
  'levelStr': 'All',
  'escalatingChainId': 3,
  'escalatingChainName': 'Example123'},
 {'id': 21,
  'name': 'CNBC',
  'priority': 4,
  'levelStr': 'All',
  'escalatingChainId': 3,
  'escalatingChainName': 'Example456'}]

yftpprvb

yftpprvb4#

有一个更好的方法来做到这一点,通过使用像这样的generator

def item_generator(json_input, lookup_key):
    if isinstance(json_input, dict):
        for k, v in json_input.items():
            if k == lookup_key:
                yield v
            else:
                yield from item_generator(v, lookup_key)
    elif isinstance(json_input, list):
        for item in json_input:
            yield from item_generator(item, lookup_key)

字符串
这将调用一个递归调用,并给予您想要的key值,即使代码之间有列表。只需使用如下函数调用它:

for j in item_generator(p_d, i):
        {}

print(output)

相关问题