【问题标题】:json parser in pythonpython中的json解析器
【发布时间】:2015-09-01 16:50:55
【问题描述】:

使用标准 json 库,我必须在类似于这个的 json 字符串中获取 key 的值,而且 key 位置在 json 字符串中不是固定的,它可能位于多个 json 对象下,所以我将如何导航到整个 json 字符串并寻找键来获取相应的值

{
    "app": {
        "GardenCategory": {
            "label": {
                "Flower": "Rose",
                "Fruits": "Apple"
            }
        },
        "Flowers": {
            "Red_Flowers": "Rose",
            "Thorn_Flowers": "Marigold",
            "beautiful_flower": "sunflower",
        },
        "FruitState": {
            "label": {
                "Sweet Fruit": "Mango",
                "Healthy fruits": "Orange",
                "Liquid fruits": "Water-Melon",
            }
        }
}

【问题讨论】:

  • 为什么一定要开发它?为什么不使用现有的?
  • 不要写解析器,使用json模块。
  • 如果您是一个只想解析 JSON 的新手,那么创建解析器将比学习如何使用现有的解析器多很多工作。阅读documentation
  • 解析完这个json后,不再是字符串,而是dict。然后问题转换为“如何在嵌套字典中找到键”。

标签: python arrays json


【解决方案1】:

如 cmets 中所述,json.load() 会给你一本字典。您只需要遍历该字典,如果需要,递归地找到所需的键。

我对这样一个函数的初稿是:

def find(adict, key):
    if key in adict.keys():
        return adict[key]
    else:
        for ndict in adict.values():
            return find(ndict, key)

In [466]: adict={'a':{"b":3, "c":{"d":4}}}

In [467]: find(adict,'d')
Out[467]: 4

In [468]: find(adict,'e')
...
AttributeError: 'int' object has no attribute 'keys'

由于json 字符串也可以包含列表,因此该函数也应该处理这些列表。

纠正你的例子我得到:

In [477]: adict=json.loads(txt)
In [478]: find(adict,'Flower')
Out[478]: u'Rose'

更强大的版本:

def find1(adict, key):
    if isinstance(adict, dict):
        if key in adict.keys():
            return adict[key]
        for ndict in adict.values():
            x = find1(ndict, key)
            if x: return x
    else:
        return None

【讨论】:

    【解决方案2】:

    首先,您的 json 格式不正确。您需要删除"beautiful_flower": "sunflower","Liquid fruits": "Water-Melon", 之后的逗号,您还缺少字符串末尾的括号。

    接下来你需要做的事情,如果你把它作为一个字符串,就是在 python 中把它变成一个字典。你可以这样做:

    import json
    a='{"app": {"GardenCategory": {"label": {"Flower": "Rose","Fruits": "Apple"}},"Flowers": {"Red_Flowers": "Rose","Thorn_Flowers": "Marigold","beautiful_flower": "sunflower"},"FruitState": {"label": {"Sweet Fruit": "Mango","Healthy fruits": "Orange","Liquid fruits": "Water-Melon"}}}}'
    j=json.loads(a)
    

    然后你可以尝试用一个方法递归地找到你需要的元素:

    def find(element, JSON):
        if element in JSON:
            return JSON[element]
        for key in JSON:
            if isinstance(JSON[key], dict):
                return find(element, JSON[key])
    

    这将查看第一级键并检查您想要的键是否在第一级。如果是,它将返回该值。如果它不在第一级,它将遍历所有键并在所有也是字典的值上运行查找。它将返回它找到的第一个匹配项的值。例如:

    find('Sweet Fruit', j) 将返回 Mango

    find('label', j) 将返回 {'Fruits': 'Apple', 'Flower': 'Rose'}

    如果您要查找的内容不在字典中,它将不返回任何内容

    find('foobar', j) 将返回 None

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2018-01-27
      相关资源
      最近更新 更多