如何在没有外部递归函数的情况下解析多个嵌套的 JSON 键?

Posted

技术标签:

【中文标题】如何在没有外部递归函数的情况下解析多个嵌套的 JSON 键?【英文标题】:How to parse multiple nested JSON keys without an external recursive function? 【发布时间】:2020-12-08 15:11:14 【问题描述】:

我正在开发一个 Discord Bot,它解析 API、格式化并返回数据。 我需要解析嵌套的键,特别是“current”、“today”、“day30”、“day90”和“day180”键,并且找不到直接的方法来解析。 这是 JSON 数据:


  "item": 
    "icon": "url_removed_for_obscurity",
    "icon_large": "url_removed_for_obscurity",
    "id": 859,
    "type": "Default",
    "typeIcon": "url_removed_for_obscurity",
    "name": "Example Item",
    "description": "Example Item Description",
    "current": 
      "trend": "neutral",
      "price": "1,210"
    ,
    "today": 
      "trend": "negative",
      "price": "- 16"
    ,
    "members": "true",
    "day30": 
      "trend": "negative",
      "change": "-4.0%"
    ,
    "day90": 
      "trend": "negative",
      "change": "-8.0%"
    ,
    "day180": 
      "trend": "negative",
      "change": "-3.0%"
    
  

这按预期工作:

item_desc = '';
current_vals = ''; todays_vals = ''; day30_vals = ''; day90_vals = ''; day180_vals = ''
current_trend = ''; todays_trend = ''; day30_trend = ''; day90_trend = ''; day180_trend = '';

get_item_data = requests.get(item_endpoint).json()

for key, val in get_item_data.items():
        if(query_id == str(val['id'])):
            #print('[Debug] Found Item Through API...')
            if('description' in val):
                item_desc = str(val['description'])
                await context.send(item_desc)
            if('current' in val):
                current_vals = str(val['current'])
                await context.send(current_vals)
            if('today' in val):
                todays_vals = str(val['today'])
                await context.send(todays_vals)
            if('day30' in val):
                day30_vals = str(val['day30'])
                await context.send(day30_vals)
            if('day90' in val):
                day90_vals = str(val['day90'])
                await context.send(day90_vals)
            if('day180' in val):
                day180_vals = str(val['day180'])
                await context.send(day180_vals)
            break

然后输出:

Example Item Description
'trend': 'neutral', 'price': '1,210'
'trend': 'negative', 'price': '- 16'
'trend': 'negative', 'change': '-4.0%'
'trend': 'negative', 'change': '-8.0%'
'trend': 'negative', 'change': '-3.0%'

我知道我需要这样做:

current_trend = ''; todays_trend = ''; day30_trend = ''; day90_trend = ''; day180_trend = '';
            if('current' in val):
                current_vals = str(val['current'])
                parse_current_vals = json.loads(current_vals)
                if('trend' in parse_current_vals.items()):
                    current_trend = str(parse_current_vals['trend'])
                    await context.send(current_trend)
etc

我希望它简单地返回

negative
neutral

positive

它目前什么都不返回,因为我显然没有正确解析。 我已经尝试了上述许多不同的变体,但均无济于事。最后几个小时的谷歌搜索和试验/错误让我在这里寻求建议。欢迎和赞赏任何和所有的输入。

【问题讨论】:

您的预期输出是什么?以及它与您得到的输出有何不同? @deadshot 已相应编辑。 还不清楚 我希望它简单地输出“负面”“中性”或“正面”。它目前没有输出任何内容,因为我知道我没有正确处理它。 【参考方案1】:

类似

 data = 
  "item": 
    "icon": "url_removed_for_obscurity",
    "icon_large": "url_removed_for_obscurity",
    "id": 859,
    "type": "Default",
    "typeIcon": "url_removed_for_obscurity",
    "name": "Example Item",
    "description": "Example Item Description",
    "current": 
      "trend": "neutral",
      "price": "1210"
    ,
    "today": 
      "trend": "negative",
      "price": "-16"
    ,
    "members": "true",
    "day30": 
      "trend": "negative",
      "change": "-4.0%"
    ,
    "day90": 
      "trend": "negative",
      "change": "-8.0%"
    ,
    "day180": 
      "trend": "negative",
      "change": "-3.0%"
    
  

def as_float(val):
    value = val.strip()
    if value.endswith('%'):
        value = value[:-1]
    value = value.replace(',','')
    return float(value)
collected_trends = []
interesting_keys = 'day30','today','current'
for key in interesting_keys:
    entry = data['item'][key]
    num = entry['change'] if 'change' in entry else entry['price']
    collected_trends.append([entry['trend'],as_float(num)])
print(collected_trends)

输出

[['neutral', 1210.0], ['negative', -4.0], ['negative', -16.0]]

【讨论】:

所以您会建议将整个查询存储在一个变量中,并解析系统端而不是针对我的获取请求使用 .items()? 是的 .. 维护一个“有趣的键”列表/集并直接读取它们的值。 这将返回与我的函数已经执行的相同['trend': 'negative', 'change': '-4.0%', 'trend': 'negative', 'price': '- 16'] 我遇到的问题是从“趋势”键中获取值“负”。 (然后是价格键的值)@balderman @D7L6-D6L7 代码已修改。这就是你要找的吗? 我看到“趋势”和“价格”实际上并不是关键。您如何建议解析代码的输出并抓取趋势和数字价格值...?

以上是关于如何在没有外部递归函数的情况下解析多个嵌套的 JSON 键?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有外部库的情况下解析包含对象列表的对象列表

浅谈-js递归函数

浅谈-js递归函数

在没有外部函数的情况下重现atoi()

python闭包的详细解析

如何在没有 require() 的情况下使用带有 postcss.config.js 的 Tailwind 嵌套声明