简体   繁体   English

如果可能的话,如何将Python dict转换为JSON作为列表

[英]How to convert Python dict to JSON as a list, if possible

I'm trying to serialize my Python objects into JSON using json.dumps . 我正在尝试使用json.dumps将我的Python对象序列化为JSON。 If you serialize a dict using json.dumps it will obviously be serialized as a JSON dictionary {..} ; 如果使用json.dumps序列化dict它显然会被序列化为JSON字典{..} ; if you serialize a list or a tuple , it will be a JSON array. 如果序列化listtuple ,它将是一个JSON数组。

I want to know if there's any way to easily serialize a Python dict as a JSON list , if possible. 我想知道是否有任何方法可以轻松地将Python dict序列化为JSON list ,如果可能的话。 By if possible, I mean if the keys start at 0 and are sequenced, for example: 如果可能的话,我的意思是如果键从0开始并按顺序排序,例如:

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

The above would be serialized into JSON as: '{"0": "data", "1": "data", "2": "data"}' , but I would like it to be serialized as ['data','data','data'] since the keys start at 0 and are sequenced. 以上将被序列化为JSON: '{"0": "data", "1": "data", "2": "data"}' ,但我希望它被序列化为['data','data','data']因为键从0开始并按顺序排列。

My reasoning for this is because I have lots of JSON data that is serialized from PHP, where in PHP arrays have keys and if the keys are sequenced as described above, PHP's json.encode uses arrays, if they are keyed in any other manner, they are serialized as JSON dictionaries. 我的理由是因为我有很多从PHP序列化的JSON数据,其中PHP数组中有键,如果键按照上面的顺序排序,PHP的json.encode使用数组,如果它们以任何其他方式键入,它们被序列化为JSON词典。 I want my JSON serializations to match for both my PHP and Python code. 我希望我的JSON序列化能够匹配我的PHP和Python代码。 Unfortunately, changing the PHP code isn't an option in my case. 不幸的是,在我的情况下,更改PHP代码不是一个选项。

Any suggestions? 有什么建议? The only solution I have found is to write my own function to go through and verify each python dictionary and see if it can first be converted to a list before json.dumps . 我找到的唯一解决方案是编写自己的函数来验证每个python字典,看看它是否可以在json.dumps之前首先转换为list

EDIT : This object that I'm serializing could be a list or a dict , as well, it could have additional dicts inside of it, and lists, and so on (nesting). 编辑 :我正在序列化的这个对象可能是一个list或一个dict ,它可以在其中包含额外的dicts,列表等等(嵌套)。 I'm wondering if there's any 'simple' way to do this, otherwise I believe I can write a recursive solution myself. 我想知道是否有任何'简单'的方法可以做到这一点,否则我相信我自己可以写一个递归的解决方案。 But it's always better to use existing code to avoid more bugs. 但是使用现有代码以避免更多错误总是更好。

You could convert the dictionary into a list of tuples and then sort it, as dictionary items won't necessarily come out in the order than you want them to: 您可以将字典转换为元组列表,然后对其进行排序,因为字典项不一定按顺序出现,而不是您希望它们:

items = sorted(d.items(), key=lambda item: item[0])
values = [item[1] for item in items]
json_dict = json.dumps(values)

I don't know of a solution without recursion... Although you can call your converter from inside the encode method of your custom Encoder , it would just add unnecessary complexity. 我不知道没有递归的解决方案......虽然您可以从自定义Encoderencode方法内部调用转换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"]]'

Normally you could subclass json.JSONEncoder to create your own custom JSON serializer, but that won't allow you to override built-in object types. 通常,您可以将json.JSONEncoder子类json.JSONEncoder创建自己的自定义JSON序列化程序,但这不允许您覆盖内置对象类型。

If you create your own custom dictlist object (or whatever you want to call it) that doesn't extend dict or list you should be able to override the JSONEncoder.default method to create your own custom JSON serializer. 如果您创建自己的自定义dictlist对象(或任何您想要调用的对象),它不会扩展dictlist您应该能够覆盖JSONEncoder.default方法来创建自己的自定义JSON序列化程序。

Regardless of whether you create a custom JSON serializer or recursively replace your special dict instances with lists you will need a function that accepts a dict and returns either a list or a dict as appropriate. 无论您是创建自定义JSON序列化程序还是以列表递归替换特殊dict实例,您都需要一个接受dict的函数,并根据需要返回listdict

Here's one implementation: 这是一个实现:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM