我正在嘗試將字典項串列展開為嵌套字典結構,該結構應包含以下結構
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)
uj5u.com熱心網友回復:
使用 adefaultdict可以為您節省很多必須有條件地設定字典結構的麻煩:
>>> 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}}}
uj5u.com熱心網友回復:
這是一種方法。它從一個已經有 2 個空總線的物件開始,減少了一些屬性雜耍。這種方法可能不如defaultdict,但它更直接地說明了解壓信號背后的邏輯。我不能假裝知道你在做什么,但這一切似乎都是一種糟糕的方式,而且在某種程度上毫無意義。這種方法的真正結果是什么~你分配None了一個信號名稱。所有的資料都已經存在,改變它的形式可能完全沒有必要。您的 2 Busses 可能應該只是一個Bus類的單獨實體,該類具有可以決議和組織提供給它的資料的方法。如果你使用 adataclass你也可以使用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 busses
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/377172.html
上一篇:python中的輸入字典
