如何从嵌套数据结构(例如从解析 JSON)中提取单个值?

2025-01-14 08:50:00
admin
原创
105
摘要:问题描述:我编写了一些代码来从 Web API 获取数据。我能够解析来自 API 的 JSON 数据,但得到的结果看起来相当复杂。以下是一个例子:>>> my_json {'name': 'ns1:timeSeriesResponseType', 'declaredType': 'org.c...

问题描述:

我编写了一些代码来从 Web API 获取数据。我能够解析来自 API 的 JSON 数据,但得到的结果看起来相当复杂。以下是一个例子:

>>> my_json
{'name': 'ns1:timeSeriesResponseType', 'declaredType': 'org.cuahsi.waterml.TimeSeriesResponseType', 'scope': 'javax.xml.bind.JAXBElement$GlobalScope', 'value': {'queryInfo': {'creationTime': 1349724919000, 'queryURL': 'http://waterservices.usgs.gov/nwis/iv/', 'criteria': {'locationParam': '[ALL:103232434]', 'variableParam': '[00060, 00065]'}, 'note': [{'value': '[ALL:103232434]', 'title': 'filter:sites'}, {'value': '[mode=LATEST, modifiedSince=null]', 'title': 'filter:timeRange'}, {'value': 'sdas01', 'title': 'server'}]}}, 'nil': False, 'globalScope': True, 'typeSubstituted': False}

查看这些数据,我可以看到我想要的具体数据:1349724919000标记为 的值'creationTime'

我怎样才能编写直接获取该值的代码?

我不需要任何搜索逻辑来找到这个值。当我查看响应时,我可以看到我需要什么;我只需要知道如何将其转换为特定代码以硬编码方式提取特定值。我阅读了一些教程,所以我知道我需要使用它[]来访问嵌套列表和字典的元素;但我无法弄清楚它在复杂情况下的具体工作原理。

更一般地说,我如何才能找出数据的“路径”并为其编写代码?


解决方案 1:

作为参考,让我们看看原始 JSON 的样子,具有漂亮的格式:

>>> print(json.dumps(my_json, indent=4))
{
    "name": "ns1:timeSeriesResponseType",
    "declaredType": "org.cuahsi.waterml.TimeSeriesResponseType",
    "scope": "javax.xml.bind.JAXBElement$GlobalScope",
    "value": {
        "queryInfo": {
            "creationTime": 1349724919000,
            "queryURL": "http://waterservices.usgs.gov/nwis/iv/",
            "criteria": {
                "locationParam": "[ALL:103232434]",
                "variableParam": "[00060, 00065]"
            },
            "note": [
                {
                    "value": "[ALL:103232434]",
                    "title": "filter:sites"
                },
                {
                    "value": "[mode=LATEST, modifiedSince=null]",
                    "title": "filter:timeRange"
                },
                {
                    "value": "sdas01",
                    "title": "server"
                }
            ]
        }
    },
    "nil": false,
    "globalScope": true,
    "typeSubstituted": false
}

这让我们更清楚地看到数据的结构。

在具体情况下,我们首先要查看解析数据中键下的相应值。这是另一个字典;我们可以用同样的方式'value'访问其键的值,然后从那里进行类似操作。'queryInfo'`'creationTime'`

为了获得所需的值,我们只需将这些访问一个接一个地放置:

my_json['value']['queryInfo']['creationTime'] # 1349724919000

解决方案 2:

我只需要知道如何以硬编码的方式将其转换为特定代码以提取特定值。

如果您再次访问 API,新数据可能不符合代码的预期。您可能会发现添加一些错误处理很有用。例如,用于.get()访问数据中的字典,而不是索引:

name = my_json.get('name') # will return None if 'name' doesn't exist

另一种方法是明确测试密钥:

if 'name' in resp_dict:
    name = resp_dict['name']
else:
    pass

但是,如果需要进一步访问,这些方法可能会失败。的占位符结果None不是字典或列表,因此尝试以这种方式访问​​它将再次失败(使用TypeError)。由于“简单胜过复杂”和“请求原谅比请求许可更容易”,因此直接的解决方案是使用异常处理:

try:
    creation_time = my_json['value']['queryInfo']['creationTime']
except (TypeError, KeyError):
    print("could not read the creation time!")
    # or substitute a placeholder, or raise a new exception, etc.

解决方案 3:

以下是从简单 JSON 数据加载单个值并与 JSON 进行相互转换的示例:

import json

# load the data into an element
data={"test1": "1", "test2": "2", "test3": "3"}

# dumps the json object into an element
json_str = json.dumps(data)

# load the json to a string
resp = json.loads(json_str)

# print the resp
print(resp)

# extract an element in the response
print(resp['test1'])

解决方案 4:

尝试一下。

在这里,我仅从COVID API(JSON 数组)中获取状态代码。

import requests

r = requests.get('https://api.covid19india.org/data.json')

x = r.json()['statewise']

for i in x:
  print(i['statecode'])

解决方案 5:

尝试一下:

from functools import reduce
import re


def deep_get_imps(data, key: str):
    split_keys = re.split("[\\[\\]]", key)
    out_data = data
    for split_key in split_keys:
        if split_key == "":
            return out_data
        elif isinstance(out_data, dict):
            out_data = out_data.get(split_key)
        elif isinstance(out_data, list):
            try:
                sub = int(split_key)
            except ValueError:
                return None
            else:
                length = len(out_data)
                out_data = out_data[sub] if -length <= sub < length else None
        else:
            return None
    return out_data


def deep_get(dictionary, keys):
    return reduce(deep_get_imps, keys.split("."), dictionary)

然后你可以像下面这样使用它:

res = {
    "status": 200,
    "info": {
        "name": "Test",
        "date": "2021-06-12"
    },
    "result": [{
        "name": "test1",
        "value": 2.5
    }, {
        "name": "test2",
        "value": 1.9
    },{
        "name": "test1",
        "value": 3.1
    }]
}

>>> deep_get(res, "info")
{'name': 'Test', 'date': '2021-06-12'}
>>> deep_get(res, "info.date")
'2021-06-12'
>>> deep_get(res, "result")
[{'name': 'test1', 'value': 2.5}, {'name': 'test2', 'value': 1.9}, {'name': 'test1', 'value': 3.1}]
>>> deep_get(res, "result[2]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[-1]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[2].name")
'test1'
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1355  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   8  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   9  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用