如何将连接集合映射到匿名对象或namedtupple集合?

时间:2018-04-13 11:49:17

标签: python dictionary mapping

您是否了解使用内部集合将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功能?

2 个答案:

答案 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'