当前位置: 首页 > 知识库问答 >
问题:

是否字典,json(转储,加载),默认保留从python 3.7的顺序?

施轶
2023-03-14

我一直认为字典是无序的,这意味着我们必须使用像OrderedDector这样的东西来记住插入顺序。

当我看到python文档时,有人提到,从python3.7开始,dict是有序的。

我对这一点没有什么怀疑,

  1. 如果命令保留插入顺序,这是否意味着即使集合中的default的也会这样做?
  2. 如果我有下面这样的数据,那么json.dumps和json.loads功能与默认数据,

编辑:https://docs.python.org/3/library/json.html (json文档)

在Python3.7之前,dict不保证是有序的,因此输入和输出通常是加扰的,除非集合。特别要求订购信息通信技术。从Python3.7开始,常规dict变成了顺序保留,因此不再需要指定集合。OrderedDict用于JSON生成和解析。

至于第二个疑问,我在python json文档中找到了上述语句,但我想知道这是否适用于嵌套的defaultdict数据。

# example defaultdict data for 2 doubt. 

from collections import defaultdict
data = defaultdict(dict)

data["0"]["a"] = "Google"
data["0"]["b"] = "Google"
data["0"]["c"] = "Google"
data["1"]["a"] = "Google"
data["1"]["b"] = "Google"
data["1"]["c"] = "Google"
data["2"]["a"] = "Google"
data["2"]["b"] = "Google"
data["2"]["c"] = "Google"
data["3"]["c"] = "Google"
data["3"]["b"] = "Google"
data["3"]["a"] = "Google"

json.dumps(data) # will these operations preserve the order 
json.loads(data) 

我已经试过了,这是为了维护秩序,但我想确定的是,不管怎样,这都会维护秩序。

共有1个答案

南宫凯康
2023-03-14

由于python 3.7将dict的实现作为规范的一部分进行排序,而不是作为实现的副作用,因此可以可靠地使用dict。OrderedDict仍然很有用,原因如下:

  • 向后兼容性(如果需要支持较旧的python版本)
  • 使用move_to_end和pop_项重新排序键
  • 更清晰的意图:如果您依赖于您的dict密钥被订购,订购的dict会使其变得明显,但您确实会损失一些性能
  • 比较OrderedDicts时会考虑键的顺序,而dicts则忽略键的顺序(感谢@ShadowRanger的通知):

例如:

from collections import OrderedDict

one_dict = {"a": 1, "b": 2}
another_dict = {"b": 2, "a": 1}

one_ordered_dict = OrderedDict(a=1, b=2)
another_ordered_dict = OrderedDict(b=2, a=1)

print(one_dict == another_dict)
# True
print(one_ordered_dict == another_ordered_dict)
# False

如果需要这些要求中的任何一个,OrderedDict可以帮助您,否则您可以使用常规dict。

关于json。转储,这是一个不同的问题:

据我所知,JSONEncoder迭代键,所以它不应该改变顺序。

如果需要,可以强制进行词典排序:

>>> json.dumps({'b': 1, 'a': 2}, sort_keys=True)
'{"a": 2, "b": 1}'

关于加载,我不明白为什么不能保留顺序,但我承认我在解码器和扫描仪的源代码中迷失了方向。

如果你愿意,你可以使用:

>>> json.loads('{"b": 2, "a": 1}', object_pairs_hook=OrderedDict)
OrderedDict([('b', 2), ('a', 1)])

上述方法也适用于嵌套的dicts:递归调用_iterencode_dict,并对所有dicts的键进行排序。

的确:

>>> json.dumps({'b': 1, 'a': {'d': 1, 'c': 3}}, sort_keys=True)
'{"a": {"c": 3, "d": 1}, "b": 1}'

干杯!

 类似资料:
  • 问题内容: 我注意到JSON对象中元素的顺序不是原始顺序。 JSON列表的元素呢?他们的订单得到维护吗? 问题答案: 是的,JSON数组中元素的顺序得以保留。从RFC 7159开始-JavaScript对象表示法(JSON)数据交换格式 (重点是我的): 对象是零个或多个名称/值对的 无序 集合,其中名称是字符串,值是字符串,数字,布尔值,null,对象或数组。 数组是零个或多个值的 有序 序列。

  • 我有一个画布,其中包含带有的对象和带有的其他对象。当我将此画布转换为JSON并重新加载时。这些对象具有默认属性。即没有居中旋转,对象是可选择的。我可以知道为什么会发生这种情况吗?很明显,像centeredRotation、可选这样的属性不包含在JSON中。 {“type”:“rect”,“originX”:“左”,“originY”:“顶部”,“左”:92,“顶部”:53,“宽度”:150,“高度

  • 问题内容: Java的foreach循环是否从第一个对象开始,并且以线性方式工作到结束?例如 是否总是先处理字符串“ Zoe”,然后处理“ Bob”等?没有排序发生?我已经对它进行了测试,但没有找到任何东西,但是我需要保证,在文档中找不到任何东西。 问题答案: 是。顺序不变。这适用于Java类集合框架的所有类型的集合,这些集合实现由for循环使用的迭代器接口。如果要对数组进行排序,则可以使用Arr

  • 我知道React可能会异步和批量地执行状态更新,以进行性能优化。因此,在调用之后,您永远不能相信会更新状态。但是,您是否信任React按照调用时的顺序更新状态 相同的组件? 不同的组件? 任何有文档支持的答案都是非常感谢的。

  • 问题内容: 我特别想知道PostgreSQL。给出以下人为的示例: 从外部查询返回的名称是否保证与内部查询的顺序相同? 问题答案: 不,在外部查询中按以下顺序排序: 内部(子)查询返回结果集。如果按此顺序进行排序,则保证从内部(子)查询传递到外部查询的中间结果集将按照您指定的方式进行排序,但是在外部查询中不对结果进行排序通过处理内部查询结果集生成的结果集,不能保证以任何方式进行排序。

  • 我正在尝试使用JOLT进行JSON转换,我想我已经很接近了,但是我不能做的是为每个当前没有出现的字段添加一个新字段。 我已经阅读了很多教程,下面的代码是我希望能够工作的。然而,它似乎没有添加到新的“名称”字段中。 这是我的震撼: 这是输出: 我希望它是这样的: 谁能告诉我哪里出错了?显然,默认值用于添加新项目,但它似乎没有执行任何操作。