您是否了解使用内部集合将dict映射到匿名对象的工具?
我有一些数据来源:
data = [
{
"SpacehipId": 1,
"SpacehipName": "Independence",
"OfficerId": 1,
"OfficerName": "John Smith"
},
{
"SpacehipId": 1,
"SpacehipName": "Independence",
"OfficerId": 2,
"OfficerName": "Steven Smith"
},
{
"SpacehipId": 2,
"SpacehipName": "Liberty",
"OfficerId": 3,
"OfficerName": "Michel Smith"
}
]
我需要一个能够获取这些数据的函数,并返回我可以使用的函数:
mapping = [
{
"objectName": "spaceShip",
"keys": ["SpacehipId","SpacehipName"]
},
{
"objectName": "spaceShip.Crew",
"keys": ["OfficerId","OfficerName"]
}
]
result = blackboxfunction(data, mapping)
blackboxfunction函数工作的结果,就像这样:
>>> print(result[0].SpacehipId)
1
>>> print(result[1].Crew[0].OfficerName)
Michel Smith
我应该使用哪些工具和库来实现blackbox功能?
答案 0 :(得分:0)
您可以使用namedtuple
集合,它将支持您的优先语法。
from collections import namedtuple
Spaceship = namedtuple('Spaceship', 'spaceshipID spaceshipName officerID officerName')
x = Spaceship(1, "Independece", 1, "John Smith")
x.spaceshipName
更简单的是,您可以定义此函数将任何字典转换为namedtuple
:
def convert(dictionary, name):
return namedtuple(name, dictionary.keys())(**dictionary)
然后使用它:
d = {
"SpacehipId": 2,
"SpacehipName": "Liberty",
"OfficerId": 3,
"OfficerName": "Michel Smith"
}
convert(d, "Spaceship")
因此,您可以使用以下方法轻松转换所有数据:
[convert(d, "Spaceship") for d in data]
答案 1 :(得分:0)
class Object():
def __init__(self, data):
self.__dict__ = data
def groupBy(data, fields):
hashes = {}
items = {}
for d in data:
group = {g: d[g] for g in d.keys() if g in fields}
h = sum([hash(d[value]) for value in group])
if hashes.get(h) == None:
hashes[h] = group
item = {f: d[f] for f in d.keys() if f not in fields}
if items.get(h) == None:
items[h] = []
items[h].append(item)
return [{**hashes[h], **{'data': items[h]}} for h in hashes]
def joinedDictToObjects(data, mapping):
mappedFields = [field for m in mapping for field in mapping[m]]
groupFields = [field for field in data[0].keys() if field not in mappedFields]
grouped = groupBy(data, groupFields)
result = []
for g in grouped:
objRaw = {key: g[key] for key in g if key not in ['data']}
for m in mapping:
objRaw[m] = [Object({a: g['data'][i][a] for a in g['data'][i] if a in mapping[m]}) for i, item in enumerate(g['data'])]
result.append(Object(objRaw))
return result
使用:
mapping = { "Crew": ["OfficerId", "OfficerName"] }
result = joinedDictToObjects(data, mapping)
输出:
>>> print(result[0].SpacehipId)
1
>>> print(result[1].Crew[0].OfficerName)
'Michel Smith'