从一个大的 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 对象
从 Component 中的 Service 解析 JSON 数组对象