如何正确解析简单json的JSON?

1 投票
1 回答
1156 浏览
提问于 2025-04-17 05:07

我可以有以下的JSON字符串:

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ],
      [ { "cid" : "1",
          "name" : "Something"
        } ],
      [ { "cid" : 1,
          "name" : "Something-else"
        } ]
    ] }

或者以下其中之一:

{"error":"some-error"}

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ],
      [ { "cid" : "1",
          "name" : ""
        } ],
      [ { "cid" : 1,
          "name" : "Something-else"
        } ]
    ] }

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ] ] }

所以,我不确定所有的子元素和内容是否都在里面。要获取Something的值,做以下检查是否足够:

if jsonstr.get('response'):
    jsonstr = jsonstr.get('response')[1][0]
    if jsonstr:
        name = jsonstr.get('name')
        if jsonstr: # I don't need empty value
            # save in the database

这个过程可以简化吗?

1 个回答

2

你不能保证每次解析你的内部对象时,它们的顺序都是一样的,所以用索引来引用属性为 name 且值为 Something 的对象并不安全。

与其嵌套一堆 if 语句,不如使用一种叫做 列表推导式 的方法。注意,如果你遍历 response 这个键,你会得到一个包含多个列表的列表,每个列表里面都有一个字典:

>>> data = {"response":[[{"uid":123456,"name":"LA_"}],[{"cid":"1","name":"Something"}],[{"cid":1,"name":"Something-else"}]]}
>>> [lst for lst in data.get('response')]
[[{'name': 'LA_', 'uid': 123456}], [{'name': 'Something', 'cid': '1'}], [{'name': 'Something-else', 'cid': 1}]]

如果你取每个列表中的第一个项目(lst[0]),你就会得到一个对象的列表:

>>> [lst[0] for lst in data.get('response')]
[{'name': 'LA_', 'uid': 123456}, {'name': 'Something', 'cid': '1'}, {'name': 'Something-else', 'cid': 1}]

接着,如果你在列表推导式中添加一个 if 条件来匹配对象的 name 属性,你就会得到一个只包含你想要的对象的列表:

>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something']
[{'name': 'Something', 'cid': '1'}]

然后通过索引这个最终列表中的第一个项目,你就能得到你想要的对象:

>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something'][0]
{'name': 'Something', 'cid': '1'}

这样你就可以把这个过程变成一个函数,继续你的工作:

def get_obj_by_name(data, name):
    objects = [lst[0] for lst in data.get('response', []) if lst[0].get('name') == name]
    if objects:
        return objects[0]

    return None

print get_obj_by_name(data, 'Something')
# => {'name': 'Something', 'cid': '1'}

print get_obj_by_name(data, 'Something')['name']
# => 'Something'

而且这个函数应该很健壮,如果找不到 response 这个键,它会返回 None

print get_obj_by_name({"error":"some-error"}, 'Something')
# => None

撰写回答