【问题标题】:how to parse json where key is variable in python?如何解析json,其中key在python中是可变的?
【发布时间】:2014-09-22 09:14:29
【问题描述】:

我正在解析一个 json 格式的日志文件, 并以 key : value 对的形式包含数据。

我被困在键本身可变的地方。请看附件代码

在这段代码中,我可以访问用户名、事件类型、ip 等键。

我的问题是访问“提交”键中的值

i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1是一个可变键,会因不同的用户而改变,

如何将其作为变量访问?

{
    "username": "batista",        
    "event_type": "problem_check",      
    "ip": "127.0.0.1",
    "event": {
        "submission": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "input_type": "choicegroup",
                "question": "",
                "response_type": "multiplechoiceresponse",
                "answer": "MenuInflater.inflate()",
                "variant": "",
                "correct": true
            }
        },
        "success": "correct",
        "grade": 1,
        "correct_map": {
            "i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                "hint": "",
                "hintmode": null,
                "correctness": "correct",
                "npoints": null,
                "msg": "",
                "queuestate": null
            }
        }

这是我解决问题的代码:

import json
import pprint
with open("log.log") as infile:
# Loop until we have parsed all the lines.
for line in infile:
    # Read lines until we find a complete object
    while (True):
        try:
            json_data = json.loads(line)

            username = json_data['username']
            print "username :- " + username

        except ValueError:                
            line += next(infile)

如何访问 i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1 密钥和

这个键里面的数据??

【问题讨论】:

    标签: python json logging logfiles


    【解决方案1】:

    你不需要提前知道key,你可以简单地遍历字典:

    for k,v in obj['event']['submission'].iteritems():
       print(k,v)
    

    【讨论】:

      【解决方案2】:

      假设您有一个d = {"a":"b"} 类型的字典,那么d.popitem() 会给您一个元组("a","b"),即(key,value)。所以使用它你可以在不知道键的情况下访问键值对。

      如果j 是主字典,那么j["event"]["submission"].popitem() 会给你元组

      ("i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1": {
                      "input_type": "choicegroup",
                      "question": "",
                      "response_type": "multiplechoiceresponse",
                      "answer": "MenuInflater.inflate()",
                      "variant": "",
                      "correct": true
                  })
      

      希望这就是你要问的。

      【讨论】:

        【解决方案3】:

        使用 python json 模块,您最终会得到来自上述 JSON 数据的解析值字典

         import json
         parsed = json.loads(this_sample_data_in_question)
         # parsed is a dictionary, so are "correct_map" and "submission" dictionary keys within "event" key 
        

        因此,您可以像普通字典一样遍历数据的键、值,如下所示:

         for k, v in parsed.items():
             print k, v
        

        现在您可以像这样快速找到“i4x-IITB-CS101-problem-33e4aac93dc84f368c93b1d08fa984fc_2_1”键的(可能的不同值):

        import json
        
        parsed = json.loads(the_data_in_question_as_string)
        event = parsed['event']
        
        for key, val in event.items():
            if key in ('correct_map', 'submission'):
                section = event[key]
                for possible_variable_key, its_value in section.items():
                    print possible_variable_key, its_value
        

        当然,可能有更好的方法来遍历字典,但是如果您的数据类型比此处发布的数据大得多,您可以根据自己的编码品味或性能来选择一种。

        【讨论】:

        • 感谢 farzad 的回复,我已经添加了我的代码,请检查一下,我怎样才能在其中安装您的代码?
        • 上面的示例代码将适用于问题中提到的问题。变量“its_value”是您问题的答案。它是一个字典,键为“hint”、“hintmode”……但是我认为您阅读日志文件行的方式不正确。不需要 while Truenext(infile)for 循环将读取文件的所有行并尝试解析每一行的 JSON 内容。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-22
        • 2019-11-02
        • 1970-01-01
        • 2021-06-30
        相关资源
        最近更新 更多