我正在将一个C ++程序移植到Python。在某些地方,它使用std::set
来存储定义自己的比较运算符的对象。由于Python标准库没有等效的std::set
(一个有序键值映射数据结构),我尝试使用普通字典,然后在迭代时对其进行排序,如下所示:
def __iter__(self):
items = self._data.items()
items.sort()
return iter(items)
但是,分析表明,.sort()
到__cmp__
的所有来电都是严重的瓶颈。我需要一个更好的数据结构 - 本质上是一个排序字典。有谁知道现有的实施?如果不这样做,关于我应该如何实现这一点的任何建议?读取性能比写入性能更重要,时间比内存更重要。
如果每个键支持多个值,则加分,例如C ++ std::multimap
。
请注意,OrderedDict
类不符合我的需要,因为它按插入顺序返回项目,而我需要使用__cmp__
方法对它们进行排序。
答案 0 :(得分:5)
您应该使用sort(key=...)
您使用的关键功能将与您已使用的cmp相关。优点是key函数被调用n次,而cmp被称为nlog n次,而key通常是cmp所做工作的一半
如果您可以加入__cmp__()
,我们可能会向您展示如何将其转换为关键功能
如果您在修改之间进行了大量迭代,则应该缓存已排序项的值。
答案 1 :(得分:5)
对于排序字典,你可以(ab)使用python的timsort的稳定性:基本上,保持项目部分排序,在需要时在最后追加项目,切换“脏”标志,并在迭代之前对剩余项进行排序。有关详细信息和实施,请参阅此条目(A Martelli的回答): Key-ordered dict in Python
答案 2 :(得分:3)
Python没有内置的数据结构,尽管bisect
模块提供了使用适当高效的算法保持排序列表的功能。
如果您有一个排序键列表,可以将它与collections.defaultdict(list)
结合使用,以提供类似多图的功能。
答案 3 :(得分:0)
在他的书“Programming in Python 3”中,Mark Summerfield介绍了一个排序的字典类。源代码在this zip archive中可用 - 查找SortedDict.py。在书中详细描述了SortedDict类(我非常推荐)。它支持用于比较的任意键和每个键的多个值(Python中的任何字典都可以,因此,我认为这不是什么大问题。)