从一个大 json 变量到对象

From a big json variable to objects

我有一个相当大的 json 流,我想从中提取数据并将这些数据转换为对象,或者可能是字典。

我已经成功地从数据中提取了 4 个列表:admin_fname、admin_sname、admin_type 和 admin_email。 现在我有 4 个长度相等的列表,我想进一步处理这些数据,以便我得到包含管理员的 fname、sname、类型和电子邮件的对象。

我试过以下方法:

data = response.json()
admins = [item['admin_user'] for item in data['orgs']]
admin_fname = [item['firstname'] for item in admins]
admin_sname = [item['surname'] for item in admins]
admin_type =  [item['type'] for item in admins]
admin_email =  [item['primary_email'] for item in admins]

admin_data = {}

for (a, b, c, d) in zip(admin_fname, admin_sname, admin_type, admin_email):
    admin_data[admin_fname].append()
    admin_data[admin_sname].append()
    admin_data[admin_type].append()
    admin_data[admin_email].append()

但是,也许并不奇怪,我收到错误“TypeError: unhashable type: 'list'”

谁能告诉我将所有 4 个 lists/sets 的元素组合成连贯对象的更好方法?

I have a rather large json stream from which I want to pull data and turn this data into objects, or a dictionary maybe.

我认为这是前进的方向

from dataclasses import dataclass
from typing import List

data = [{'admin_fname': 'Jack', 'admin_sname': 'Ken', 'admin_type': 'the_type', 'admin_email': 'kk@some.com'},
        {'admin_fname': 'Dan', 'admin_sname': 'Borg', 'admin_type': 'the_type', 'admin_email': 'zz@some.com'}]


@dataclass
class Admin:
    admin_fname: str
    admin_sname: str
    admin_type: str
    admin_email: str


admins: List[Admin] = [Admin(**entry) for entry in data]
print(admins)

输出

[Admin(admin_fname='Jack', admin_sname='Ken', admin_type='the_type', admin_email='kk@some.com'), Admin(admin_fname='Dan', admin_sname='Borg', admin_type='the_type', admin_email='zz@some.com')]

这里有两个常见问题。如何表示单个数据点,以及如何存储这些数据点。

表示单个数据点

你有很多选择,但我只强调 3:

元组

您可以将您的对象视为一组按特定顺序排列的值。你已经有了这一行:

for (a, b, c, d) in zip(admin_fname, admin_sname, admin_type, admin_email):

更好的命名:

for (fname, sname, type, email) in zip(admin_fname, admin_sname, admin_type, admin_email):

或使用元组:

for admin in zip(admin_fname, admin_sname, admin_type, admin_email):

您可以像这样通过索引访问这些字段中的每一个:

email = admin[3]

但是,一段时间后,要知道哪个数据是哪个索引会变得困难。

词典

您可以将每个数据点表示为字典。您只需要将每个字段分配给一个键:

for (fname, sname, type, email) in zip(admin_fname, admin_sname, admin_type, admin_email):
    admin = {
        "fname": fname,
        "sname": sname,
        "type": type,
        "email": email,
    }

然后,您可以使用以下键访问每个字段:

email = admin["email"]

然而,字符串键仍然很容易出错

创建 class

最面向对象的方法是创建一个 class:

class Admin:
    def __init__(self, fname, sname, type, email):
        self.fname = fname
        self.sname = sname
        self.type = type
        self.email = email

然后创建一个对象:

for (fname, sname, type, email) in zip(admin_fname, admin_sname, admin_type, admin_email):
    admin = Admin(fname, sname, type, email)

并且您可以像访问对象一样访问每个字段:

email = admin.email

使用数据 class 也是一个不错的选择,因为

存储数据

现在,你如何存储这些数据:

列表

最直接的,就是把它放回相同顺序的列表中。

有元组:

admins = [t for t in zip(admin_fname, admin_sname, admin_type, admin_email)]

有字典:

admins = [{"fname": fname, "sname": sname, "type": type, "email": email} for (fname, sname, type, email) in zip(admin_fname, admin_sname, admin_type, admin_email)]

有对象:

admins = [Admin(fname, sname, type, email) for (fname, sname, type, email) in zip(admin_fname, admin_sname, admin_type, admin_email)]

然后您可以使用索引访问每个单独的点

词典

您可以将所有数据存储在字典中。但是,此时您需要决定一个唯一的键来表示每个数据点。出于您的目的,这可能不是最好的主意。