作为一名java开发人员,我需要一些技巧如何在python 2中解决这个问题。我在python中的技能处于初始状态。但现在问题是:
我们为设备提供服务,这些设备以一种格式报告一些技术统计数据,我们无法更改。服务器运行python。 主要报告以字典形式出现,我们需要保存json方式。从dict到json的转换不是问题,但转换平面并使用点分隔键需要转换。
也许一个例子可以说明我想说的话。这是来自设备的格式,将其命名为:
{
'Device.DeviceInfo.SoftwareVersion': 'ote-2.2.1',
'Device.GatewayInfo.ProductClass': 'OEM-TX23',
'Device.GatewayInfo.SerialNumber': 'A223142D1CC7',
'Device.Ethernet.Interface.1.MaxBitRate': 1000,
'Device.HomePlug.Interface.1.AssociatedDevice.1.RxPhyRate': 522,
'Device.HomePlug.Interface.1.AssociatedDevice.1.TxPhyRate': 706,
'Device.HomePlug.Interface.1.AssociatedDevice.1.Active': 1,
'Device.HomePlug.Interface.1.AssociatedDevice.1.MACAddress': 'af:49:79:e4:64:fc',
'Device.HomePlug.Interface.1.AssociatedDevice.2.RxPhyRate': 544,
'Device.HomePlug.Interface.1.AssociatedDevice.2.TxPhyRate': 0,
'Device.HomePlug.Interface.1.AssociatedDevice.2.Active': 1,
'Device.HomePlug.Interface.1.AssociatedDevice.2.MACAddress': 'af:49:79:e4:64:dd',
'Device.Ethernet.Interface.2.MaxBitRate': 1000,
'Device.HomePlug.Interface.2.AssociatedDevice.1.RxPhyRate': 671,
'Device.HomePlug.Interface.2.AssociatedDevice.1.TxPhyRate': 607,
'Device.HomePlug.Interface.2.AssociatedDevice.1.Active': 1,
'Device.HomePlug.Interface.2.AssociatedDevice.1.MACAddress': 'bf:49:79:e4:64:fc',
'Device.HomePlug.Interface.2.AssociatedDevice.2.RxPhyRate': 340,
'Device.HomePlug.Interface.2.AssociatedDevice.2.TxPhyRate': 0,
'Device.HomePlug.Interface.2.AssociatedDevice.2.Active': 1,
'Device.HomePlug.Interface.2.AssociatedDevice.2.MACAddress': 'bf:49:79:e4:64:dd'
}
源中的Integer值表示此接口的接口索引和AssociatedDevices。因此,整数背后的部分应该是多个词典列表。结果中不应包含的整数值。
我们需要以下嵌套结构才能将它持久保存到数据库,尤其是mysql docstore。再次,从嵌套dict到json的转换不是问题。
以下是我们需要的格式:
{
'Device': {
'GatewayInfo': {
'SerialNumber': 'A223142D1CC7',
'ProductClass': 'OEM-TX23'
},
'DeviceInfo': {
'SoftwareVersion': 'ote-2.2.1'
},
'Ethernet': {
'Interface': [{
'MaxBitRate': 1000
}, {
'MaxBitRate': 1000
}]
},
'HomePlug': {
'Interface': [{
'AssociatedDevice': [{
'RxPhyRate': 522,
'TxPhyRate': 706,
'Active': 1,
'MACAddress': 'af:49:79:e4:64:fc',
}, {
'RxPhyRate': 544,
'TxPhyRate': 0,
'Active': 1,
'MACAddress': 'af:49:79:e4:64:dd',
}]
}, {
'AssociatedDevice': [{
'RxPhyRate': 671,
'TxPhyRate': 607,
'Active': 1,
'MACAddress': 'bf:49:79:e4:64:fc',
}, {
'RxPhyRate': 340,
'TxPhyRate': 0,
'Active': 1,
'MACAddress': 'bf:49:79:e4:64:dd',
}]
}]
}
}
}
更新 第一个答案是部分正确的,除了整数之后的部分应转换为包含其余为字典的列表。
答案 0 :(得分:3)
您可以迭代原始字典以递归方式添加keys
并将值添加到最终项目中:
new_dict = {}
for key, value in my_dict.items():
k_list = key.split('.')
temp_dict = new_dict
for k in k_list[:-1]:
if k not in temp_dict:
temp_dict[k] = {}
temp_dict = temp_dict[k]
temp_dict[k_list[-1]] = value
其中my_dict
是您提到的原始dict对象。
new_dict
持有的最终价值为:
{
"Device":{
"GatewayInfo":{
"SerialNumber":"A223142D1CC7",
"ProductClass":"OEM-TX23"
},
"DeviceInfo":{
"SoftwareVersion":"ote-2.2.1"
},
"HomePlug":{
"Interface":{
"1":{
"AssociatedDevice":{
"1":{
"RxPhyRate":522,
"Active":1,
"TxPhyRate":706,
"MACAddress":"af:49:79:e4:64:fc"
},
"2":{
"Active":1,
"MACAddress":"af:49:79:e4:64:dd",
"RxPhyRate":544,
"TxPhyRate":0
}
}
},
"2":{
"AssociatedDevice":{
"1":{
"RxPhyRate":671,
"Active":1,
"TxPhyRate":607,
"MACAddress":"bf:49:79:e4:64:fc"
},
"2":{
"RxPhyRate":340,
"MACAddress":"bf:49:79:e4:64:dd",
"TxPhyRate":0,
"Active":1
}
}
}
}
},
"Ethernet":{
"Interface":{
"1":{
"MaxBitRate":1000
},
"2":{
"MaxBitRate":1000
}
}
}
}
}
答案 1 :(得分:1)
这应该有效。只需将未转换的dict
传递给convert
,它就会返回转换后的dict
def convert(data):
to_convert = set()
new_dict = {}
for key, value in data.items():
path_stack = []
k_list = key.split('.')
temp_dict = new_dict
for k in k_list[:-1]:
path_stack.append(k)
if k.isnumeric():
to_convert.add(tuple(path_stack))
if k not in temp_dict:
temp_dict[k] = {}
temp_dict = temp_dict[k]
temp_dict[k_list[-1]] = value
for path in sorted(to_convert, key=len, reverse=True):
current_level = new_dict
for k in path[:-2]:
current_level = current_level[k]
if isinstance(current_level[path[-2]], dict):
new_level = [current_level[path[-2]][i] for i in sorted(current_level[path[-2]].keys())]
else:
new_level = current_level[path[-2]]
current_level[path[-2]] = new_level
return new_dict
答案 2 :(得分:0)
如果你想深入了解python,你可能会对模块dotteddict感兴趣。
这是一个有点棘手但非常有趣的“pythonic”代码。在某个时刻,它不会将数字键转换为列表,但其中的一些概念绝对值得花时间。