字典、json(转储、加载)、defaultdict是否保留了python3.7的顺序?
我一直认为字典是无序的,这意味着我们必须使用像 OrderedDict 这样的东西来让它记住插入顺序。
当我看到 python 文档时,有人提到从 python 3.7 dict 是订购的。
我对此几乎没有怀疑,
- 如果 dict 保留插入顺序,这是否意味着即使
defaultdict在集合中也会这样做? - 如果我有如下数据,那么 json.dumps 和 json.loads 功能如何使用 defaultdict 数据,
编辑:https : //docs.python.org/3/library/json.html (json 文档)
在 Python 3.7 之前,不能保证 dict 是有序的,因此输入和输出通常会被打乱,除非 collections.OrderedDict 被特别要求。从 Python 3.7 开始,常规 dict 成为顺序保留,因此不再需要为 JSON 生成和解析指定 collections.OrderedDict。
至于第二个疑问,我在 python json docs 中找到了上面的语句,但我想知道这是否适用于嵌套的 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)
我已经尝试过这些并且它是保留顺序,但我想确保无论如何这将始终保留顺序。
回答
Python 字典
由于python 3.7 dict 的实现是作为规范的一部分进行排序的 ,而不是作为实现的副作用,因此可以可靠地使用它。OrderedDict 仍然有用有几个原因:
- 向后兼容性(如果您需要支持较旧的 python 版本)
- 使用move_to_end和pop_item重新排序键
- 更清晰的意图:如果你依赖你的 dict 键被排序,OrderedDict 使它变得明显,但你确实失去了一些性能
- 比较 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 转储/加载
关于json.dump,这是一个不同的问题:
据我所知,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)])
嵌套字典
上述适用于嵌套类型的字典以及:_iterencode_dict被称为递归,和键排序的所有类型的字典。
的确:
>>> json.dumps({'b': 1, 'a': {'d': 1, 'c': 3}}, sort_keys=True)
'{"a": {"c": 3, "d": 1}, "b": 1}'
干杯!
THE END
二维码