5

我正在尝试使用 .将我的 Python 对象序列化为 JSON json.dumps。如果你序列化一个dictusingjson.dumps它显然会被序列化为一个 JSON 字典{..};如果您序列化 alist或 a tuple,它将是一个 JSON 数组。

如果可能的话,我想知道是否有任何方法可以轻松地将 Python 序列化为dictJSON list。如果可能的话,我的意思是如果键从 0 开始并按顺序排列,例如:

{0:'data',1:'data',2:'data}

上面将被序列化为 JSON 为:'{"0": "data", "1": "data", "2": "data"}',但我希望它被序列化,['data','data','data']因为键从 0 开始并按顺序排列。

我的理由是因为我有很多从 PHP 序列化的 JSON 数据,其中 PHP 数组有键,如果键按上述顺序排列,PHP 的json.encode使用数组,如果它们以任何其他方式键入,它们被序列化作为 JSON 字典。我希望我的 JSON 序列化匹配我的 PHP 和 Python 代码。不幸的是,就我而言,更改 PHP 代码不是一种选择。

有什么建议么?我找到的唯一解决方案是编写自己的函数来遍历并验证每个 python 字典,看看它是否可以先转换为listbefore json.dumps

编辑:我正在序列化的这个对象可以是 alist或 a dict,它内部也可以有额外的 dicts 和列表,等等(嵌套)。我想知道是否有任何“简单”的方法可以做到这一点,否则我相信我可以自己编写一个递归解决方案。但是使用现有代码来避免更多错误总是更好。

4

3 回答 3

2

您可以将字典转换为元组列表,然后对其进行排序,因为字典项不一定按您希望的顺序出现:

items = sorted(d.items(), key=lambda item: item[0])
values = [item[1] for item in items]
json_dict = json.dumps(values)
于 2013-04-14T06:09:21.957 回答
2

我不知道没有递归的解决方案......虽然您可以从encode您的 custom 方法内部调用您的转换器Encoder,但这只会增加不必要的复杂性。

In [1]: import json

In [2]: d = {"0": "data0", "1": "data1", "2": {"0": "data0", "1": "data1", "2": "data2"}}

In [3]: def convert(obj):
   ...:     if isinstance(obj, (list, tuple)):
   ...:         return [convert(i) for i in obj]
   ...:     elif isinstance(obj, dict):
   ...:         _, values = zip(*sorted(obj.items()))  
   ...:         return convert(values)
   ...:     return obj

In [4]: json.dumps(convert(d))
Out[4]: '["data0", "data1", ["data0", "data1", "data2"]]'
于 2013-04-14T08:32:44.523 回答
0

通常,您可以json.JSONEncoder创建自己的自定义 JSON 序列化程序的子类,但这不允许您覆盖内置对象类型。

如果您创建自己的dictlist不扩展的自定义对象(或任何您想调用的对象),dict或者list您应该能够覆盖该JSONEncoder.default方法以创建您自己的自定义 JSON 序列化程序。

无论您是创建自定义 JSON 序列化程序还是dict用列表递归替换您的特殊实例,您都需要一个接受 adict并根据需要返回 alist或 a的函数dict

这是一个实现:

def convert_to_list(obj):
    obj_list = []
    for i in range(len(obj)):
        if i not in obj:
            return obj  # Return original dict if not an ordered list
        obj_list.append(obj[i])
    return obj_list
于 2013-04-14T07:18:29.453 回答