python - Python dicts 如何保持密钥顺序
问题描述
由于 Python 3.6 字典保持插入/键顺序。
我与一位同事就如何实现这一点发生了争论。他说这一定是通过使用列表或其他集合来保持密钥顺序来实现的。我怀疑可能有一些更微妙的东西在起作用。
我做了以下比较:
# Python 3.4.3
d = {1: 2, 2:3, 3:4}
od = OrderedDict(d)
print(sys.getsizeof(d)) # 288
print(sys.getsizeof(od)) # 1304
# Python 3.6.3
d = {1: 2, 2:3, 3:4}
print(sys.getsizeof(d)) # 240
的大小OderedDict
是巨大的,我绝对可以在后台使用列表来查看它。然而,常规字典的大小并没有发生任何变化,所以我对常规字典也使用列表来保持插入顺序这一事实持怀疑态度。
那么,较新的 python 版本中的常规 dicts 究竟是如何保持密钥顺序的呢?
解决方案
严格来说,这是一个实现细节。Python 只指定 adict
确实记住键顺序,而不是它是如何做到的。
Python 3.6 不保证键顺序;dict
这是CPython中该类型的实验性重新实现。当(如预期的那样)该实验被视为成功时,Python 本身需要在 Python 3.7 中保留键顺序。
dict
在 CPython 中,类型本身的 C 实现被修改。我不确定具体如何(您可以在此处查看详细信息),但在内存中保留一个附加列表可能比在 Python 级别执行等效操作更有效,这正是这样OrderedDict
做的。它甚至不是一个list
拥有密钥的 Python:它是一个纯 Python 链表,因此内存需求如此之大也就不足为奇了。
推荐阅读
- maven - 如何使用完整的布尔逻辑强制激活 Maven 配置文件?
- javascript - 如何将变量分配给 API 调用中的解构数据?
- swift - UITextView 避免 collectionViewCell 被点击
- html-agility-pack - 使用 HtmlWeb.LoadFromWebAsync 的 HtmlAgilityPack 不会调用 PreRequest(或 PostResponse)处理程序
- reactjs - 使用firebase在创建反应应用程序中推送通知
- docusaurus - 根据当前页面显示不同的侧边栏
- python - data_utils.is_generator_or_sequence 总是返回 False
- aws-cdk - cdk LS 失败,因为它没有找到应用程序
- r - 尝试从 Twitter API 流式传输时出错
- autodesk-forge - 我在哪里可以在 JOB POST 上设置检查引用?