【问题标题】:Parsing JSON to do math?解析 JSON 来做数学?
【发布时间】:2019-07-20 22:27:03
【问题描述】:

我是编程新手(尤其是 JSON 格式),所以请原谅我没有使用正确的术语 :) 使用 Python 3.7 Requests 模块,我收到 JSON 响应。为了简单起见,我举了一个例子:

{
    "Bob":
  {
  "Age": "15",
  "LastExamGrade": "45",
  },

    "Jack":
  {
  "Age": "16",
  "LastExamGrade": "58",
  }
}

我想做的是解析 JSON 响应以从每个响应/结构中提取两个项目并将其保存到这样的列表中(我认为这称为元组的元组?):

[("Bob","45"),("Jack","58")]

然后,在收到这样做之后,我会收到另一个类似的响应,例如以下(唯一改变的是考试成绩):

{
    "Bob":
  {
  "Age": "15",
  "LastExamGrade": "54",
  },

    "Jack":
  {
  "Age": "16",
  "LastExamGrade": "70",
  }
}

我还想将姓名和成绩保存到元组(列表)中。

最后,我想从每个人的最后一次考试成绩中减去他们的第一次考试成绩,并将其保存到最终列表中,其中包括姓名、期末考试成绩和成绩改进,如下所示:

[("Bob","54","9"),("Jack","67","12")]

使用 Python 3 最简单​​的方法是什么?至于我自己的研究,我在整个 StackOverflow 上都进行了搜索,但找不到像我这样解析 JSON 的方法(例如,在我的情况下,名称在花括号之外),并且难以进行数学运算对于 JSON 项目。

【问题讨论】:

  • 你需要了解字典
  • @ScottHunter 您好,感谢您的回复。我对字典是什么有一点了解,但我并不真正熟悉如何使用它们来做我想做的事情。你有什么建议吗?

标签: arrays json python-3.x string math


【解决方案1】:

我建议使用像 pandas 这样的专用计算包:

first_exam_grades = pd.DataFrame.from_dict(first_exam_results, orient='index').astype(int)
second_exam_grades = pd.DataFrame.from_dict(second_exam_results, orient='index').astype(int)
improvements = second_exam_grades.LastExamGrade.to_frame()
improvements['Improvement'] = second_exam_grades.LastExamGrade - first_exam_grades.LastExamGrade

这将为您提供如下所示的内容:

现在你可以随心所欲地输出它

list(zip(*([improvements.index.tolist()] + [improvements[c].values.tolist() for c in improvements])))

这会给你[('Bob', 54, 9), ('Jack', 70, 12)]你想要的。

【讨论】:

    【解决方案2】:

    一种可能的解决方案,使用协程。协程receive_message 为每个学生保存消息中的最后两个值LastExamGrade,并生成学生姓名、上一年级和上一年级改进的列表:

    json_messages = [
    # 1st message:
    {
       "Bob":
      {
      "Age": "15",
      "LastExamGrade": "45",
      },
    
        "Jack":
      {
      "Age": "16",
      "LastExamGrade": "58",
      }
    },
    # 2nd message
    {
        "Bob":
      {
      "Age": "15",
      "LastExamGrade": "54",
      },
    
        "Jack":
      {
      "Age": "16",
      "LastExamGrade": "70",
      }
    },
    # 3nd message (optional)
    {
        "Bob":
      {
      "Age": "15",
      "LastExamGrade": "14",
      },
    
        "Jack":
      {
      "Age": "16",
      "LastExamGrade": "20",
      }
    }
    ]
    
    def receive_message():
        d, message = {}, (yield)
        while True:
            for k, v in message.items():
                d.setdefault(k, []).append(v['LastExamGrade'])
                d[k] = d[k][-2:] # store max last two messages
            message = yield [(k, *tuple(v if len(v)==1 else [v[1], str(int(v[1])-int(v[0]))])) for k, v in d.items()]
    
    receiver = receive_message()
    next(receiver) # prime coroutine
    
    for msg in json_messages:
        print(receiver.send(msg))
    

    打印:

    [('Bob', '45'), ('Jack', '58')]
    [('Bob', '54', '9'), ('Jack', '70', '12')]
    [('Bob', '14', '-40'), ('Jack', '20', '-50')]
    

    【讨论】:

    • 感谢您的回答!我发现亚历克斯的答案有点简单,但你的答案也可以!
    猜你喜欢
    • 2013-01-15
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    相关资源
    最近更新 更多