首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >json.dumps()排序键(顶层除外)

json.dumps()排序键(顶层除外)
EN

Stack Overflow用户
提问于 2022-02-01 22:58:07
回答 2查看 403关注 0票数 1

需要转储一堆对象。我想对嵌套对象的键进行排序,同时保持顶级键的顺序。以下对所有键进行排序:

代码语言:javascript
复制
json.dumps(dict_of_objs, sort_keys=True, default=vars)    

谢谢

坏溶液

我可以运行如下内容,但这似乎是许多不必要的处理:

代码语言:javascript
复制
for key in dict_of_objs.keys():
    sorted_str = json.dumps(dict_of_objs[key], sort_keys=True, default=vars)
    dict_of_objs[key] = json.loads(sorted_str)

json.dumps(dict_of_objs)    
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-01 23:32:31

编辑

注释指出,不需要知道键的值,只要让lt始终返回False,就可以完全禁用排序

代码语言:javascript
复制
#!/usr/bin/env python3
import json
class UnSortableString(str):
    def __lt__(self, other):
        return False

normal_dict = {"zzz" : [5,4,3], "aaa": [100,3] }
print(json.dumps(normal_dict, sort_keys=True))

mydict = {UnSortableString("zzz") : [5,4,3], UnSortableString("aaa"): [100,3] }
print(json.dumps(mydict, sort_keys=True))

产出:

代码语言:javascript
复制
{"aaa": [100, 3], "zzz": [5, 4, 3]}
{"zzz": [5, 4, 3], "aaa": [100, 3]}

因为在我的例子中,我知道顶级键的值,所以我想出了下面的黑客解决方案:

代码语言:javascript
复制
#!/usr/bin/env python3
import json
class FakeString(str):
    order = ["first", "second", "last"]
    def __lt__(self, other):
        if self in FakeString.order and other in FakeString.order:
            return FakeString.order.index(self) < FakeString.order.index(other)
        return super.__lt__(self, other) 

normal_dict = {"last" : [5,4,3], "second": [100,3] }
print(json.dumps(normal_dict, sort_keys=True))

mydict = {FakeString("last") : [5,4,3], FakeString("second"): [100,3] }
print(json.dumps(mydict, sort_keys=True))

产出:

代码语言:javascript
复制
{"last": [5, 4, 3], "second": [100, 3]}
{"second": [100, 3], "last": [5, 4, 3]}
票数 1
EN

Stack Overflow用户

发布于 2022-02-01 23:59:41

我的解决方案--我认为它和你的一样--但我认为你可以让 it 返回False。

代码语言:javascript
复制
from json import JSONEncoder


class WrappedDict(dict):

    def items(self):
        # https://github.com/python/cpython/blob/main/Lib/json/encoder.py#L353
        # Return our wrapped items to sorted.
        return (WrappedItem(item) for item in super().items())


class WrappedItem(tuple):

    def __lt__(self, other):
        # https://docs.python.org/3/library/functions.html#sorted
        # Fake out sorted by just saying no item, ie. (k, v), is ever less than.
        return False

root = {
    "b": 2,
    "a": 1,
    "c": {
        "b": 2,
        "a": [{
            "z": 15,
            "a": 1,
        }]
    }
}

wrapped_root = WrappedDict(root)


print ('root')
print (root)

print ('sort_keys=True with wrapped root')
print (JSONEncoder(sort_keys=True).encode(wrapped_root))

print ('sort_keys=True with root')
print (JSONEncoder(sort_keys=True).encode(root))

print ('sort_keys=False with wrapped_root')
print (JSONEncoder(sort_keys=False).encode(wrapped_root))

print ('sort_keys=False with root')
print (JSONEncoder(sort_keys=False).encode(root))

输出

代码语言:javascript
复制
root
{'b': 2, 'a': 1, 'c': {'b': 2, 'a': [{'z': 15, 'a': 1}]}}
sort_keys=True with wrapped root
{"b": 2, "a": 1, "c": {"a": [{"a": 1, "z": 15}], "b": 2}}
sort_keys=True with root
{"a": 1, "b": 2, "c": {"a": [{"a": 1, "z": 15}], "b": 2}}
sort_keys=False with wrapped_root
{"b": 2, "a": 1, "c": {"b": 2, "a": [{"z": 15, "a": 1}]}}
sort_keys=False with root
{"b": 2, "a": 1, "c": {"b": 2, "a": [{"z": 15, "a": 1}]}}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70948651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档