我试图将字典项列表解压为嵌套的字典结构,该结构应该包含以下结构
Bus
Message
Fieldname我目前有一种在总线中获取消息的方法,但这只会导致将一条消息添加到每个总线中,因为我最终会用新消息覆盖总线中的字典。实际产出如下
{'BUS_A': {'MSG_1': None}, 'BUS_B': {'MSG_2': None}}如何从输入数据(包括总线项、消息和字段)创建以下所需的输入?
这是一个完整的、可执行的示例,说明了我目前所要做的工作。
signals = [{"bus":"BUS_A", "message":"MSG_1", "fieldname":"Signal1"},
{"bus":"BUS_A", "message":"MSG_2", "fieldname":"Signal2"},
{"bus":"BUS_B", "message":"MSG_3", "fieldname":"Signal3"},
{"bus":"BUS_B", "message":"MSG_4", "fieldname":"Signal4"}]
desired_output = {"BUS_A":
{"MSG_1":
{"Signal1":None},
"MSG_2":
{"Signal2":None},
},
"BUS_B":
{"MSG_3":
{"Signal3":None},
"MSG_4":
{"Signal4":None},
}
}
def Unflatten(signals):
buses = {item['bus']:{} for item in signals}
for bus in buses:
for item in signals:
if item['bus'] == bus:
buses[bus] = {item['message']:None}
print(buses)
Unflatten(signals)发布于 2021-12-08 16:59:45
使用defaultdict可以节省大量麻烦,必须有条件地设置字典的结构:
>>> signals = [{"bus":"BUS_A", "message":"MSG_1", "fieldname":"Signal1"},
... {"bus":"BUS_A", "message":"MSG_1", "fieldname":"Signal2"},
... {"bus":"BUS_B", "message":"MSG_2", "fieldname":"Signal3"},
... {"bus":"BUS_B", "message":"MSG_2", "fieldname":"Signal4"}]
>>> from collections import defaultdict
>>> buses = defaultdict(lambda: defaultdict(dict))
>>> for s in signals:
... buses[s["bus"]][s["message"]][s["fieldname"]] = None
...
>>> buses
defaultdict(<function <lambda> at 0x00000265E25451F0>, {'BUS_A': defaultdict(<class 'dict'>, {'MSG_1': {'Signal1': None, 'Signal2': None}}), 'BUS_B': defaultdict(<class 'dict'>, {'MSG_2': {'Signal3': None, 'Signal4': None}})})如果没有defaultdict,您需要根据需要将每个值初始化为一个空字典:
>>> buses = {}
>>> buses = {}
>>> for s in signals:
... if s["bus"] not in buses:
... buses[s["bus"]] = {}
... if s["message"] not in buses[s["bus"]]:
... buses[s["bus"]][s["message"]] = {}
... buses[s["bus"]][s["message"]][s["fieldname"]] = None
...
>>> buses
{'BUS_A': {'MSG_1': {'Signal1': None, 'Signal2': None}}, 'BUS_B': {'MSG_2': {'Signal3': None, 'Signal4': None}}}发布于 2021-12-08 17:17:43
这里有一种方法。它通过从一个已经有2个空总线的对象开始,减少了一些属性杂耍。这种方法可能不如defaultdict,但它更直接地说明了不平放信号背后的逻辑。我不能假装知道你在做什么,但这似乎是一种糟糕的做法,而且在某种程度上是毫无意义的。这个方法的真正结果是什么?你把None分配给一个信号名。所有的数据都已经存在,更改它的形式可能是完全没有必要的。您的2Busse可能只是一个Bus类的单独实例化,它具有可以解析和组织输入给它的数据的方法。如果您使用dataclass,您还可以使用asdict (当/如果需要的话)将它的属性传递给期望数据作为dict的任何东西。
def unflatten(signals) -> dict:
busses = {'BUS_A':dict(), 'BUS_B':dict()}
for obj in signals:
bus, msg, sig = obj['bus'], obj['message'], obj['fieldname']
if not msg in busses[bus]:
busses[bus][msg] = dict()
busses[bus][msg][sig] = None
return busseshttps://stackoverflow.com/questions/70278826
复制相似问题