如果您打算连续地从字典中添加和删除键,那么您确实需要使用适当的数据结构来解决问题的东西——不是哈希表(或哈希表加列表,如SortedOrderedDict
-type 配方),而是平衡树(或等价物,如跳过列表)。
如果您环顾一下 PyPI,您会发现许多选项。我的建议是blist
。尽管它的数据结构可能不如其他一些结构那么优化(因为 B+Tree 比二叉树宽得多),但对于您遇到的几乎所有用例来说,它可能已经足够好了。并且它具有完整且经过良好测试的界面,包括经过良好测试的性能保证。它被其他严肃的项目大量使用。
如果您正在处理树性能确实很关键的罕见情况之一,您可能应该查看各种红黑树、展开树、跳过列表等实现。我以前用过bintrees
,它有一个很棒的接口(例如,您可以通过索引访问键和值,甚至可以对树进行切片,以及将其视为 a dict
,并且作者已经考虑并避免了所有潜在的歧义),但我还没有认真地测试过它。
或者,如果您的键和值确实都是较小的整数,您可能需要考虑使用 Cython 将 C++ 包装map<int, int>
在 Pythonic 接口中。(在 C++ 之上提供一个完整的接口是不太可能的map
,但无论如何您通常都不需要它。)或者,或者,修改其中一个实现,例如bintrees.FastRBTree
存储和比较long
而不是PyObject*
.
另一方面,如果您只是要一次创建所有字典然后使用它,则有一个更简单的答案。对其进行排序,并将其粘贴在OrderedDict
. 那么你不需要标准库之外的任何东西。
sorted_dict = collections.OrderedDict(sorted(d.iteritems()))
从对另一个答案的评论中,您说“我无权安装新模块......”
首先,确保这是真的。您可能确实有权在用户站点包目录中安装模块。或者,如果virtualenv
已安装和/或您使用 3.3 和 built-in venv
,更好的是,您可能有权创建 venv 并将模块安装到其中。
但如果是这样,您需要做的就是将文件从blist
/ bintrees
/whatever 复制到您的项目中。
您可能遇到的问题是这些包中的大多数都包含 C 扩展模块,这意味着您必须能够构建它们(嗯,build_ext -i
它们)。如果您的系统没有安装 Python 开发文件和编译器工具链,则不能这样做。在这种情况下,您正在寻找最好的纯 Python 解决方案。bintrees
带有一个纯 Python 实现,它与普通的 C 扩展实现相同,但速度较慢。当然,它仍然是 O(log N),只是常数因子要高得多。如果 N 足够大,它仍然是一个巨大的胜利;如果不是,它可能不是。
如果这听起来很合理,但是您需要帮助设置每个用户的站点包或虚拟环境,或者将模块复制到您的项目中,或者就地构建扩展等,您可能应该搜索对于现有问题,如果找不到问题,请提出新问题(如果没有其他原因,只是因为那些擅长安装问题的人不一定是数据结构方面的专家,甚至可能不会阅读本文问题)。