问题 Python相当于std :: set和std :: multimap


我正在将一个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 class不符合我的需要,因为它按插入顺序返回项目,而我需要使用它们对它们进行排序 __cmp__ 方法。


3374
2018-02-22 07:28


起源



答案:


对于排序字典,您可以(ab)使用python的timsort的稳定特性:基本上,保持项目部分排序,在需要时在末尾附加项目,切换“脏”标志,并在迭代之前对剩余项进行排序。有关详细信息和实施,请参阅此条目(A Martelli的回答): Python中按键排序的dict


5
2018-02-22 08:23





你应该用 sort(key=...)
您使用的关键功能将与您已使用的cmp相关。优点是关键函数被调用n次,而cmp被称为nlog n次,并且通常key是cmp执行的一半工作

如果你能包括你的 __cmp__() 我们可以向您展示如何将其转换为关键功能

如果在修改之间进行大量迭代,则应缓存已排序项的值。


5
2018-02-22 08:18



虽然没有直接回答有关数据结构的问题,但这无疑有助于提高性能。 +1 - EMP


答案:


对于排序字典,您可以(ab)使用python的timsort的稳定特性:基本上,保持项目部分排序,在需要时在末尾附加项目,切换“脏”标志,并在迭代之前对剩余项进行排序。有关详细信息和实施,请参阅此条目(A Martelli的回答): Python中按键排序的dict


5
2018-02-22 08:23





你应该用 sort(key=...)
您使用的关键功能将与您已使用的cmp相关。优点是关键函数被调用n次,而cmp被称为nlog n次,并且通常key是cmp执行的一半工作

如果你能包括你的 __cmp__() 我们可以向您展示如何将其转换为关键功能

如果在修改之间进行大量迭代,则应缓存已排序项的值。


5
2018-02-22 08:18



虽然没有直接回答有关数据结构的问题,但这无疑有助于提高性能。 +1 - EMP


Python没有内置的数据结构,尽管如此 bisect 模块提供了使用适当有效的算法保持排序列表的功能。

如果你有一个排序键列表,你可以将它与一个 collections.defaultdict(list) 提供类似多图的功能。


3
2018-02-22 07:37





在他的书中“用Python编程3“,Mark Summerfield介绍了一个排序的字典类。源代码可用于 这个zip档案  - 寻找SortedDict.py。在书中详细描述了SortedDict类(我非常推荐)。它支持用于比较的任意键和每个键的多个值(Python中的任何字典都可以,因此我认为这不是什么大问题)。


0
2018-02-22 08:10