首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不平整字典结构到嵌套字典

不平整字典结构到嵌套字典
EN

Stack Overflow用户
提问于 2021-12-08 16:54:58
回答 2查看 79关注 0票数 0

我试图将字典项列表解压为嵌套的字典结构,该结构应该包含以下结构

代码语言:javascript
复制
Bus
   Message
          Fieldname

我目前有一种在总线中获取消息的方法,但这只会导致将一条消息添加到每个总线中,因为我最终会用新消息覆盖总线中的字典。实际产出如下

代码语言:javascript
复制
{'BUS_A': {'MSG_1': None}, 'BUS_B': {'MSG_2': None}}

如何从输入数据(包括总线项、消息和字段)创建以下所需的输入?

这是一个完整的、可执行的示例,说明了我目前所要做的工作。

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-08 16:59:45

使用defaultdict可以节省大量麻烦,必须有条件地设置字典的结构:

代码语言:javascript
复制
>>> 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,您需要根据需要将每个值初始化为一个空字典:

代码语言:javascript
复制
>>> 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}}}
票数 1
EN

Stack Overflow用户

发布于 2021-12-08 17:17:43

这里有一种方法。它通过从一个已经有2个空总线的对象开始,减少了一些属性杂耍。这种方法可能不如defaultdict,但它更直接地说明了不平放信号背后的逻辑。我不能假装知道你在做什么,但这似乎是一种糟糕的做法,而且在某种程度上是毫无意义的。这个方法的真正结果是什么?你把None分配给一个信号名。所有的数据都已经存在,更改它的形式可能是完全没有必要的。您的2Busse可能只是一个Bus类的单独实例化,它具有可以解析和组织输入给它的数据的方法。如果您使用dataclass,您还可以使用asdict (当/如果需要的话)将它的属性传递给期望数据作为dict的任何东西。

代码语言:javascript
复制
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 busses
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70278826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档