使用Python在JSON参数中动态值

col17t5w  于 2023-01-27  发布在  Python
关注(0)|答案(2)|浏览(170)

需要说明的是,我正在使用CoinMarketCaps API练习Python技能。
下面的代码很好用:

import json

# 1 JSON string in list, works
info_1_response = ['{"status": {"timestamp": "2023-01-25T22:59:58.760Z", "error_code": 0, "error_message": null, "elapsed": 16, "credit_count": 1, "notice": null}, "data": {"BTC": {"id": 1, "name": "Bitcoin", "symbol": "BTC"}}}']

for response in info_1_response:
    info_1_dict = json.loads(response)
    #print(info_1_dict) #works
    data = info_1_dict['data']['BTC']
    print(f"only id = {data['id']}")
    • 输出**:仅id = 1

然而,如果我在一个列表中有2个响应,我将如何获得每个符号的ID(BTC/ETH)?代码:

info_2_response = ['{"status": {"timestamp": "2023-01-25T22:59:58.760Z", "error_code": 0, "error_message": null, "elapsed": 16, "credit_count": 1, "notice": null}, "data": {"BTC": {"id": 1, "name": "Bitcoin", "symbol": "BTC"}}}', '{"status": {"timestamp": "2023-01-25T22:59:59.087Z", "error_code": 0, "error_message": null, "elapsed": 16, "credit_count": 1, "notice": null}, "data": {"ETH": {"id": 1027, "name": "Ethereum", "symbol": "ETH"}}}']
for response in info_2_response:
    info_2_dict = json.loads(response)
    #print(info_2_dict) #works
    print(info_2_dict['data']) #works
    • 输出:**

{'BTC': {'id': 1, 'name': 'Bitcoin', 'symbol': 'BTC'}}
{'ETH': {'id': 1027, 'name': 'Ethereum', 'symbol': 'ETH'}}
但是如果我***只***想要ID呢?看起来我需要一个动态参数:
data = info_2_dict['data']['DYNAMIC PARAMETER-(BTC/ETH)']
print(f"only id = {data['id']}")

    • 所需输出:**1,1027

这可能吗?

hfyxw5xn

hfyxw5xn1#

只需迭代另一个级别:

>>> for response in info_2_response:
...     response = json.loads(response)
...     for coin, data in response['data'].items():
...         print(coin, data['id'])
...
BTC 1
ETH 1027

我们可以使用map(json.loads, ...)从循环体中删除一些样板文件,而且既然你知道dict中只有一项,你就可以使用可迭代解包:

>>> for response in map(json.loads, info_2_response):
...     [(coin, data), *_] = response['data'].items()
...     print(coin, data['id'])
...
BTC 1
ETH 1027

如果您 * 期望 * 只有一个,您可能希望抛出一个错误,因此可以执行以下操作:

>>> for response in map(json.loads, info_2_response):
...     [(coin, data)] = response['data'].items()
...     print(coin, data['id'])
...
BTC 1
ETH 1027

注意,在顶级版本中,[(coin, data), *_] = response['data'].items()在dict中有多个项时不会失败,其余项被赋给一个名为_的列表,我们忽略了它,但这只是一个“一次性”变量的常规名称。
但是,另一个版本将失败:

>>> response
{'status': {'timestamp': '2023-01-25T22:59:59.087Z', 'error_code': 0, 'error_message': None, 'elapsed': 16, 'credit_count': 1, 'notice': None}, 'data': {'ETH': {'id': 1027, 'name': 'Ethereum', 'symbol': 'ETH'}}}
>>> response['data']['FOO'] = "FOO STUFF"
>>> [(coin, data)] = response['data'].items()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 1)
>>>
js81xvg6

js81xvg62#

只要data字典只有一个键,就可以执行以下操作:

import json

info_2_response = [
    """{"status": {"timestamp": "2023-01-25T22:59:58.760Z", "error_code": 0, "error_message": null, "elapsed": 16, "credit_count": 1, "notice": null},
    "data": {"BTC": {"id": 1, "name": "Bitcoin", "symbol": "BTC"}}}""",
    """{"status": {"timestamp": "2023-01-25T22:59:59.087Z", "error_code": 0, "error_message": null, "elapsed": 16, "credit_count": 1, "notice": null},
    "data": {"ETH": {"id": 1027, "name": "Ethereum", "symbol": "ETH"}}}""",
]
for response in info_2_response:
    info_2_dict = json.loads(response)
    print(list(info_2_dict["data"].values())[0]["id"])

这将打印:

1
1027

代码的工作原理是使用字典的.values()方法获取一个值列表,因为只有一个值,所以我们只从列表中获取第一个值,然后查找id属性。
我们可以扩展复合语句,使运算更清楚一些:

for response in info_2_response:
    info_2_dict = json.loads(response)
    all_values = info_2_dict["data"].values()
    first_value = list(all_values)[0]
    id = first_value["id"]
    print(id)

相关问题