Python相当于java.util.SortedSet?

时间:2009-03-09 21:58:15

标签: python data-structures

有人知道Python是否与Java的SortedSet接口等效吗?

以下是我正在寻找的内容:假设我有foo类型的对象,我知道如何比较foo类型的两个对象以查看foo1是否为“大于“或”小于“foo2。我想要一种在列表foo中存储L类型的许多对象的方法,这样每当我遍历列表L时,我按顺序获取对象,根据比较方法我定义

编辑:

我想我每次修改时都可以使用字典或列表sort(),但这是最好的方法吗?

7 个答案:

答案 0 :(得分:12)

您可以使用bisect模块中的insort在已排序的列表中有效插入新元素:

from bisect import insort

items = [1,5,7,9]
insort(items, 3)
insort(items, 10)

print items # -> [1, 3, 5, 7, 9, 10]

请注意,这与SortedSet不直接对应,因为它使用列表。如果您多次插入同一项目,则列表中将包含重复项。

答案 1 :(得分:12)

看看BTrees。看起来你需要其中一个。据我所知,你需要的结构将支持相对便宜的元素插入存储结构和廉价的排序操作(甚至缺乏它)。 BTrees提供了这个。

我对ZODB.BTrees有经验,他们可以扩展到成千上万的元素。

答案 2 :(得分:4)

如果您正在寻找使用类似平衡搜索树(例如红黑树)实现的Python高效容器类型的实现,那么它不是标准库的一部分。

我能够找到这个,但是:

http://www.brpreiss.com/books/opus7/

源代码可在此处获取:

http://www.brpreiss.com/books/opus7/public/Opus7-1.0.tar.gz

我不知道源代码是如何获得许可的,我自己也没有使用它,但是如果你对滚动自己的容器类不感兴趣,那么它将是一个开始寻找的好地方。

PyAVL这是一个实现AVL树的C模块。

此外,this thread可能对您有用。它包含了很多关于如何使用bisect模块来增强现有Python字典以执行所要求的建议。

当然,使用insort()这种方式对于插入和删除来说相当昂贵,因此请仔细考虑您的应用程序。实施适当的数据结构可能是一种更好的方法。

在任何情况下,要了解是否应该对数据结构进行排序或在迭代时对其进行排序,您必须知道是要插入很多还是重复迭代。保持数据结构排序是有意义的,如果你相对不频繁地修改其内容,但重复迭代它。相反,如果您一直插入和删除成员但是相对不频繁地遍历集合,则在迭代之前对键集合进行排序会更快。没有一种正确的方法。

答案 3 :(得分:3)

如果您只需要密钥,并且没有相关的值,Python会提供以下集:

s = set(a_list)

for k in sorted(s):
    print k

但是,每次执行此操作时,您都将对该集进行排序。 如果开销过高,您可能需要查看HeapQueues。它们可能不像优雅和“Pythonic”,但它们可能适合您的需求。

答案 4 :(得分:3)

与blist.sortedlist类似,sortedcontainers模块提供排序列表,排序集和排序的dict数据类型。它在底层实现中使用了一个修改过的B树,并且在大多数情况下比blist更快。

sortedcontainers模块是纯Python,因此安装很简单:

pip install sortedcontainers

然后例如:

from sortedcontainers import SortedList, SortedDict, SortedSet
help(SortedList)

sortedcontainers模块具有100%的覆盖率测试和数小时的压力。这是一个非常全面的performance comparison,其中列出了您为此考虑的大多数选项。

答案 5 :(得分:2)

使用blist package中的blist.sortedlist

from blist import sortedlist

z = sortedlist([2, 3, 5, 7, 11])
z.add(6)
z.add(3)
z.add(10)

print z

这将输出:

sortedlist([2, 3, 3, 5, 6, 7, 10, 11])

生成的对象可以像python列表一样使用。

>>> len(z)
8
>>> [2 * x for x in z]
[4, 6, 6, 10, 12, 14, 20, 22]

答案 6 :(得分:0)

你有可能使用Jython吗?我只是提到它,因为使用TreeMap,TreeSet等是微不足道的。此外,如果您来自Java背景并且想要进入Pythonic方向,那么Jython非常适合使转换更容易。虽然我认识到在这种情况下使用TreeSet不会成为这种“过渡”的一部分。

对于Jython超级用户,我自己也有一个问题:无法导入blist包,因为它使用的是必须导入的C文件。但是使用blist而不是TreeSet会有什么好处吗?我们通常可以假设JVM使用的算法基本上和CPython的算法一样好吗?