将JSON数组解析为对象?

the*_*i11 7 python json

我正在尝试用Python解析一些数据我有一些JSON:

{
    "data sources": [
        "http://www.gcmap.com/"
    ],
    "metros": [
        {
            "code": "SCL",
            "continent": "South America",
            "coordinates": {
                "S": 33,
                "W": 71
            },
            "country": "CL",
            "name": "Santiago",
            "population": 6000000,
            "region": 1,
            "timezone": -4
        },
        {
            "code": "LIM",
            "continent": "South America",
            "coordinates": {
                "S": 12,
                "W": 77
            },
            "country": "PE",
            "name": "Lima",
            "population": 9050000,
            "region": 1,
            "timezone": -5
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

如果我想将"metros"数组解析为Python类Metro对象的数组,我将如何设置该类?

我刚在想:

class Metro(object):
    def __init__(self):
        self.code = 0
        self.name = ""
        self.country = ""
        self.continent = ""
        self.timezone = ""
        self.coordinates = []
        self.population = 0
        self.region = ""
Run Code Online (Sandbox Code Playgroud)

所以我想通过每个地铁并将数据放入相应的Metro对象并将该对象放入对象的Python数组中...如何循环JSON地铁?

nne*_*neo 14

如果您始终获得相同的密钥,则可以使用它**来轻松构建实例.如果您使用它只是为了保持价值,那么制作Metroa namedtuple将简化您的生活:

from collections import namedtuple
Metro = namedtuple('Metro', 'code, name, country, continent, timezone, coordinates, population, region')
Run Code Online (Sandbox Code Playgroud)

那么简单

import json
data = json.loads('''...''')
metros = [Metro(**k) for k in data["metros"]]
Run Code Online (Sandbox Code Playgroud)


Abh*_*jit 5

假设您使用json加载数据,我会在这里使用一个namedtuple列表来存储关键字'metro'下的数据

>>> from collections import namedtuple
>>> metros = []
>>> for e in data[u'metros']:
    metros.append(namedtuple('metro', e.keys())(*e.values()))


>>> metros
[metro(code=u'SCL', name=u'Santiago', country=u'CL', region=1, coordinates={u'S': 33, u'W': 71}, timezone=-4, continent=u'South America', population=6000000), metro(code=u'LIM', name=u'Lima', country=u'PE', region=1, coordinates={u'S': 12, u'W': 77}, timezone=-5, continent=u'South America', population=9050000)]
>>> 
Run Code Online (Sandbox Code Playgroud)


mar*_*eau 5

这相对容易做到,因为您已经读取了数据,该数据将为“metros”中的每个元素返回一个 Python 字典,在本例中 \xe2\x80\x94 只需遍历它并创建类实例json.load()列表Metro。我修改了该方法的调用顺序,Metro.__init__()以便更轻松地将数据从返回的字典传递给它json.load()

\n\n

由于结果中“metros”列表的每个元素都是字典,因此您可以Metro使用符号将其传递给类的构造函数**,将其转换为关键字参数。然后构造函数可以将这些值传输给它自己update()__dict__

\n\n

通过这种方式做事,而不是使用像 a 这样的东西collections.namedtuple作为一个数据容器,这是Metro一个自定义类,它使得添加您想要的其他方法和/或属性变得微不足道。

\n\n
import json\n\nclass Metro(object):\n    def __init__(self, **kwargs):\n        self.__dict__.update(kwargs)\n\n    def __str__(self):\n        fields = [\'    {}={!r}\'.format(k,v)\n                    for k, v in self.__dict__.items() if not k.startswith(\'_\')]\n\n        return \'{}(\\n{})\'.format(self.__class__.__name__, \',\\n\'.join(fields))\n\n\nwith open(\'metros.json\') as file:\n    json_obj = json.load(file)\n\nmetros = [Metro(**metro_dict) for metro_dict in json_obj[\'metros\']]\n\nfor metro in metros:\n    print(\'{}\\n\'.format(metro))\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
import json\n\nclass Metro(object):\n    def __init__(self, **kwargs):\n        self.__dict__.update(kwargs)\n\n    def __str__(self):\n        fields = [\'    {}={!r}\'.format(k,v)\n                    for k, v in self.__dict__.items() if not k.startswith(\'_\')]\n\n        return \'{}(\\n{})\'.format(self.__class__.__name__, \',\\n\'.join(fields))\n\n\nwith open(\'metros.json\') as file:\n    json_obj = json.load(file)\n\nmetros = [Metro(**metro_dict) for metro_dict in json_obj[\'metros\']]\n\nfor metro in metros:\n    print(\'{}\\n\'.format(metro))\n
Run Code Online (Sandbox Code Playgroud)\n