就地对字典进行排序

2024-02-23

如何就地对字典进行排序?它没有像这样的排序方法list.sort?

d = {3: 'three', 1: 'one', 2: 'two'}
tmp = dict(sorted(d.items()))
d.clear()
d.update(tmp)

想要这样的结果 ^ 但应该就地正确,即不使用双倍内存。对同一对象的其他引用应该会看到重新排序!


没有办法做到这一点。字典现在是保留顺序的,但只是保留 - 它们并不是为了支持复杂的顺序操作操作而设计的。

导致保留顺序的字典的字典实现更改从根本上来说在它可以支持的顺序操作类型方面非常有限。字典的哈希表将索引存储到一个密集的条目数组中,正是这个数组维护了字典的元素顺序。

在不使哈希表失效的情况下,密集数组不能任意重新排序。出于冲突解决的目的,即使删除条目也必须在其位置上留下虚拟标记,并且如果不重建完整的哈希表,则无法重用该条目的位置。

即使您尝试通过删除和替换条目来执行某种低效的手动排序,您也会积累虚拟数据并触发哈希表重建,从而消耗您不想使用的额外内存。这是一个简单的演示:

import os

os.system(f'grep VmPeak /proc/{os.getpid()}/status')

x = dict.fromkeys(range(2**16))

os.system(f'grep VmPeak /proc/{os.getpid()}/status')

for i in range(2**16):
    if i == 21845:
        os.system(f'grep VmPeak /proc/{os.getpid()}/status')
    k = next(iter(x))
    x[k] = x.pop(k)
    if i == 21845:
        os.system(f'grep VmPeak /proc/{os.getpid()}/status')

os.system(f'grep VmPeak /proc/{os.getpid()}/status')

Output:

VmPeak:    15092 kB
VmPeak:    20224 kB
VmPeak:    20224 kB
VmPeak:    24832 kB
VmPeak:    24832 kB

我们不使用实际的排序(这会消耗额外的内存或花费大量额外的时间),而是使用已经排序的字典并重复提取顺序中的第一个键并将其放置在顺序的末尾,以匹配访问模式将执行删除和替换排序来对该字典进行排序。当我们达到字典重建的阈值时,由于需要分配字典内部数据结构的第二个副本,峰值内存使用量立即跳跃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

就地对字典进行排序 的相关文章

随机推荐

  • Mfc CComboBoxEx - 如何更改背景颜色

    我有一个派生自 CComboBoxEx 的类 我正在尝试更改背景颜色 我认为它会像 ComboBox 一样工作 使用 SetBkColor 函数 但它不会改变背景颜色 这是我尝试过的 BEGIN MESSAGE MAP CMyComboBo
  • svn:转储格式文档?

    svnadmin dump 格式是否记录在某处 我想记录一个包含 svn 存储库所有元数据的数据结构 除了文件内容本身之外 它基本上与 转储 文件中的内容相同 似乎 svnkit 库会有它 或者有办法以编程方式获取此元数据 但我在过去的一个
  • 单击引导按钮显示默认颜色

    我正在尝试使用下面的代码设置按钮颜色的样式 颜色在我单击按钮之前一直有效 按钮显示默认颜色 如何指定按钮 onclick 的颜色 btn success color ffffff background color 161617 border
  • 当目标是对象时,JSON.net 将 json 数组序列化为 JArray。我怎样才能改变这一点?

    我有一个单级 json 我想将其反序列化为Dictionary
  • C++ - 类函数内数组的长度[重复]

    这个问题在这里已经有答案了 我知道有几个线程问类似的问题 但我找不到解决方案 而且我对 C 有点陌生 我想计算 DWORD 数组的长度 所以它只是一个无符号长整型 DWORD offsets 0x378 0x14 0x0 这是我的函数的标头
  • 获取 SDWebImage 缓存图像

    我想问一下SDWebImageManager下载后如何获取下载的图像 我只有通过 URL 下载它的代码 这就是我得到的 let manager SDWebImageManager SDWebImageManager sharedManage
  • 如果浏览器选项卡处于非活动状态,则 SignalR 连接超时

    如果我保持浏览器选项卡处于活动状态 至少每 5 6 分钟打开一次 我的 WebSocket 连接会通过 ping 请求保持活动状态 请参阅随附的屏幕截图 但是 如果我放弃该选项卡 10 分钟左右 ping 请求就会停止发生 WebSocke
  • 存储和编辑 Java EE 应用程序的配置

    UPDATE 请参阅我关于此主题的博客文章大约一年后撰写 http blog ringerc id au 2012 07 java ee 7 needs improvements in app html http blog ringerc
  • 如何在 Django 中的 URL 中传递 kwargs

    在 django 文档中 url 函数是这样的 url regex view kwargs None name None prefix 我有这个 url r download template P
  • Hibernate 数据库加密对应用程序完全透明

    我正在开发一个 Grails 1 0 4 项目 该项目将在不到 2 周的时间内发布 客户刚刚提出了一个要求 即数据库中的所有数据都应该加密 由于对应用程序本身中的每个数据库访问进行加密可能会花费大量时间并且容易出错 因此我寻求的解决方案是某
  • 在内部存储上播放文件时 MediaPlayer 错误-2147483648

    我正在使用android com 上的音频捕获示例 http developer android com guide topics media index html在实际设备上录制和播放音频 摩托罗拉触摸板和三星 Galaxy S 当我将音
  • 使用 Android 设计支持库从右到左导航抽屉菜单

    我正在使用 android 设计支持库 我想知道如何拥有从右到左的导航抽屉 我将重力设置为右侧 但只有导航抽屉本身移动到右侧 我想知道如何将右侧的菜单项 导航视图
  • 我无法使用 PowerShell 和 Selenium 模块启动 chrome instant

    我不确定我缺少什么 但我在 PowerShell 7 1 下安装了 Selenium 模块 但无法启动 chrome 实例 我按照以下步骤操作 从https github com adamdriscoll selenium powershe
  • PHP 无效字符错误

    运行此代码时我收到此错误 Fatal error Uncaught exception DOMException with message Invalid Character Error in test php 29 Stack trace
  • 性能类型 varchar(1) 或smallint 来存储状态 Postgres

    我将存储从 0 到 7 的状态 考虑到 Postgres 数据库的性能和空间 我想知道哪个类型字段更适合存储 varchar 1 或smallint 对了 设置一个字段varchar 1 和varchar 100 有什么区别吗 还在讨论性能
  • 如何在页脚中显示生成页面所需的持续时间?

    在调试构建期间 我想显示服务器端在页面页脚中生成页面所需的持续时间 例如 如果一个页面在服务器端花费 250 毫秒 我希望在调试版本中显示在页脚中 如何在 ASP NET MVC 项目中实现这一目标 将其添加到母版页的页脚中 Page re
  • jQuery:.select() 和 .focus() 方法区别

    在 jQuery 中 两者之间的基本区别是什么 select focus 它们合适的使用场所是什么 他们有各自的区别 select will fire when TEXT is selected 仅限于
  • 如何从 Mercurial 存储库中安全地禁用/删除大型文件目录?

    过去 我一直在 Mercurial 中使用大型文件扩展来将数据与我正在处理的代码一起保存 我认为这是一个错误 我想删除 largefiles 目录 8GB 我们的网络用户目录限制为 10 GB 我需要空间 我已经很长时间没有使用任何大文件了
  • Spark Yarn模式如何从spark-submit获取applicationId

    当我使用带有主纱线和部署模式集群的spark submit提交spark作业时 它不会打印 返回任何applicationId 并且一旦作业完成 我必须手动检查MapReduce jobHistory或spark HistoryServer
  • 就地对字典进行排序

    如何就地对字典进行排序 它没有像这样的排序方法list sort d 3 three 1 one 2 two tmp dict sorted d items d clear d update tmp 想要这样的结果 但应该就地正确 即不使用