从一个大的 json 变量到对象

Posted

技术标签:

【中文标题】从一个大的 json 变量到对象【英文标题】:From a big json variable to objects 【发布时间】:2021-10-30 04:36:25 【问题描述】:

我有一个相当大的 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 个列表/集合的元素组合成连贯对象的更好方法吗?

【问题讨论】:

你能分享一下json吗(只是一小部分) 【参考方案1】:

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

我认为这是前进的方向

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')]

【讨论】:

json 集非常大,我看到自己从中提取了几个类,但这是一个非常好的解决方案。谢谢。 @Bokkie 我很高兴能帮上忙。随意投票。 我需要更多声望才能投票... 8-( 好的。祝你好运:-) 我在插入时遇到错误...Traceback (most recent call last): File <path>, line 42, in <module> admins: List[Admin] = [Admin(**entry) for entry in data] File <path>, line 42, in <listcomp> admins: List[Admin] = [Admin(**entry) for entry in data] TypeError: __main__.Admin() argument after ** must be a mapping, not str【参考方案2】:

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

表示单个数据点

您有很多选择,但我只想强调 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"]

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

创建一个类

这样做的最 OOP 方式是创建一个类:

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

使用数据类也是一个不错的选择,如@balderman suggested

存储数据

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

列表

最直接的方法是将其放回相同顺序的列表中。

使用元组:

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)]

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

字典

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

【讨论】:

非常感谢您的广泛回答。目的是将数据保存在 excel 或 csv 文件中。那是我必须跨过的另一座桥,但似乎更微不足道。 是的!最后一个按我的想法工作。当我执行print(admins[<index>].<attribute>) 时,我得到了我的期望。谢谢!

以上是关于从一个大的 json 变量到对象的主要内容,如果未能解决你的问题,请参考以下文章

Mailchimp API 在使用 node-fetch 而不是 json 时返回一个大的 gzip 对象

漂亮地将 JSON 转储到文本

将客户端 Json 下载为 CSV

从 Component 中的 Service 解析 JSON 数组对象

Laravel - 从 JSON 数组创建对象以将其保存在 SQL 数据库中

将包含 JSON 对象的数据框展开为更大的数据框