从 JSON 响应中提取浮点密钥对值时出现 TypeError

Posted

技术标签:

【中文标题】从 JSON 响应中提取浮点密钥对值时出现 TypeError【英文标题】:TypeError when extracting float key pair value from JSON response 【发布时间】:2022-01-20 01:43:03 【问题描述】:

背景 - 我有一个函数,它接受一个名为 api_response 的变量(它本身是使用来自另一个函数的 api_response = json.loads(response.text) 格式化的,并尝试从中提取 2x 密钥对值 - 即 @987654323 @ 和 percent_complete 并打印出来。

功能 -

def unpack_response():
    api_response = api_call()
# Code Block # 1
    while "meta" not in api_response:
        id_value = "id"
        res1 = [val[id_value] for key, val in api_response.items() if id_value in val]
        id_value = "".join(res1)
        percent_value = "percent_complete"
        # The following line of code is referenced in the TypeError  
        res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
        percent_value = "".join(res2)
        print(f' Your data requested, associated with ID: id_value is percent_value complete!')
        time.sleep(5)
        continue
# Code Block # 2
    if "meta" in api_response:
        print(api_response)
unpack_response()

JSON 响应 (api_response) -

'data': 'id': '2205853', 'type': 'jobs', 'attributes': 'job_type': 'PORTFOLIO_VIEW_RESULTS', 'started_at': '2021-12-17T02:53:48Z', 'parameters': 'end_date': '2021-12-14', 'output_type': 'json', 'view_id': 304078, 'portfolio_id': 1, 'portfolio_type': 'firm', 'start_date': '2021-12-14', 'percent_complete': 0.19, 'status': 'In Progress', 'relationships': 'creator': 'links': 'self': '/v1/jobs/2205853/relationships/creator', 'related': '/v1/jobs/2205853/creator', 'data': 'type': 'users', 'id': '731221', 'links': 'self': '/v1/jobs/2205853', 'included': []

问题 - 函数返回 id 键值对没有问题并打印(假设我删除所有与 percent_complete 相关的代码),但是 "percent_complete" 键值对导致关注TypeError

错误 -

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-8a61597dcee6> in <module>
     16     if "meta" in api_response:
     17         print(api_response)
---> 18 unpack_response()

<ipython-input-38-8a61597dcee6> in unpack_response()
      8         percent_value = "percent_complete"
      9 #         res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
---> 10         res2 = [val['attributes'].get(percent_value, '') for key, val in api_response.items()]
     11         percent_value = "".join(res2)
     12         print(f' Your data requested, associated with ID: id_value is percent_value complete!')

<ipython-input-38-8a61597dcee6> in <listcomp>(.0)
      8         percent_value = "percent_complete"
      9 #         res2 = [val['attributes'][percent_value] for key, val in api_response.items() if percent_value in val['attributes']]
---> 10         res2 = [val['attributes'].get(percent_value, '') for key, val in api_response.items()]
     11         percent_value = "".join(res2)
     12         print(f' Your data requested, associated with ID: id_value is percent_value complete!')

TypeError: list indices must be integers or slices, not str

谁能帮我理解为什么id 没有问题地返回(假设我删除了所有与percent_complete 相关的代码),而percent_complete 的密钥对值却没有。这与密钥对值是浮点数有关吗?

【问题讨论】:

循环底部不需要continue。除非您中断,否则循环会自动重复。 api_responseincluded 键的值是一个列表,而不是字典。当val 是一个列表时,你不能使用val['attributes'] 它适用于id 的原因是因为你有if id_value in val 条件。 in 运算符适用于字典和列表。列表的条件失败,因此它永远不会尝试执行val[id_value] 您是否有任何理由选择使用列表理解而不是使用api_response["data"]["attributes"] 来访问数据?您的res2 = ... 代码不会检查"attributes" 是否在val 中,这就是它最终访问"included" 密钥的原因。该错误看起来像是在尝试访问api_response["included"]["attributes"],这将失败,因为included 是一个列表。 您正在遍历 api_response 字典的所有元素。有两个键和值。 data 键有一个字典作为它的值,并且它有一个 attributes 键。 included 键有一个列表作为其值,当您尝试访问其 attributes 键时会出错。 【参考方案1】:

感谢许多 cmets(感谢 Barmarrchrome),我重新编写了我的函数如下 -

def unpack_response():
    api_response = api_call()
    if "meta" not in api_response:
        id_value = "id"
        res1 = [val[id_value] for key, val in api_response.items() if id_value in val]
        id_value = "".join(res1)
        percent_value = "percent_complete"
        res2 = api_response["data"]["attributes"].get("percent_complete", '')
        print(f' Your data requested, associated with ID: id_value is res2 complete!')
        time.sleep(5)
        api_response = api_call()
    if not "meta" in api_response:
        print(api_response)
unpack_response()

【讨论】:

以上是关于从 JSON 响应中提取浮点密钥对值时出现 TypeError的主要内容,如果未能解决你的问题,请参考以下文章

使用从 JSON 数据中提取的值时出现 NSInvalidArgumentException

实现Azure密钥保管库2.0时出现Newtonsoft Json版本问题

Python - 从 JSON 响应中提取数据(使用 TomTom api)

调用 WCF Web 服务时出现错误的 Json 响应

尝试在 if 语句中检查 json 响应时出现未捕获(承诺)错误

从具有特定结构的 json 解码数据时出现问题