如何在Json对象中转换dict?

2024-10-03 11:15:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,我正在尝试用Json编码一个数据dict

我的格言是:

data = { ('analogInput', 18) : [('objectName','AI8-Voltage'),
                                ('presentValue',238.3),
                                 ('units','Volts')],
         ('analogInput', 3)  : [('objectName','AI3-Pulse'),
                                ('presentValue',100),
                                ('units','Amp')]
        }

当我尝试这样做时:foo=json.dumps(数据) 我得到了这个消息:致命错误:键必须是str、int、float、bool或None,而不是tuple

我试图寻找答案,但我不明白我该如何处理我的问题

Thanx你有答案吗


Tags: 数据答案json编码datadictunitsvoltage
2条回答

首先,并非所有类型都可以用于JSON键

Keys must be strings, and values must be a valid JSON data type (string, number, object, array, Boolean or null).

有关更多信息,请查看this

现在,作为可行的解决方案,我建议您实现两个函数,将元组转换为字符串,并将字符串转换为元组。下面提供了一个非常简单的示例:

import json
data = { ('analogInput', 18) : [('objectName','AI8-Voltage'),
                                ('presentValue',238.3),
                                 ('units','Volts')],
         ('analogInput', 3)  : [('objectName','AI3-Pulse'),
                                ('presentValue',100),
                                ('units','Amp')]
        }


def tuple_to_str(t):
    # It can be implemeneted with more options
    return str(t[0])+'_'+str(t[1])


def str_to_tuple(s):
    l =s.split('_')
    # Your first (second) item is int
    l[1] = int(l[1])
    return tuple(l)


if __name__=="__main__":
    # create a space for a dict of data with string keys
    s_data= dict()
    for key in data:
        s_data[tuple_to_str(key)] = data[key]

    x = json.dumps(s_data)

    # create a space to load the json with string keys
    raw_data = json.loads(x)

    final_data = dict()
    for key in raw_data:
        final_data[str_to_tuple(key)] = raw_data[key]

    # Ture
    print(final_data)

错误是明确的。在Python dict中,键可以是任何可哈希类型,包括元组、冻结集或冻结dict(但既不是列表,也不是集合或dict)

但在Json对象中,字典键只能是字符串、数字(int或float)、布尔值或特殊对象None

长话短说,您的输入字典不能直接转换为Json

可能的解决办法:

  • 使用不同的序列化工具。例如,pickle可以接受任何Python类型,但不能移植到非Python应用程序。但是,如果同时编写序列化和反序列化部分,也可以使用自定义序列化格式

  • 将键转换为字符串。在反序列化时,您只需将字符串转换回具有ast.literal_evel的元组:

      js = json.dumps({str(k): v for k,v in data.items()})
    

    给予:{"('analogInput', 18)": [["objectName", "AI8-Voltage"], ["presentValue", 238.3], ["units", "Volts"]], "('analogInput', 3)": [["objectName", "AI3-Pulse"], ["presentValue", 100], ["units", "Amp"]]}

    您可以使用以下内容将其加载回:

      data2 = {ast.literal_eval(k): v for k,v in json.loads(js).items()}
    

    给予{('analogInput', 18): [['objectName', 'AI8-Voltage'], ['presentValue', 238.3], ['units', 'Volts']], ('analogInput', 3): [['objectName', 'AI3-Pulse'], ['presentValue', 100], ['units', 'Amp']]}

    您可以看到json转换将元组更改为列表

相关问题 更多 >