为什么Python的标准库中没有排序的容器?


81

是否有Python设计决策(PEP)阻止将已排序的容器添加到Python?

OrderedDict不是已排序的容器,因为它是按插入顺序排序的。)


1
像collections.OrderedDict?
utdemir

1
它只是更快。哈希图的O(1)与有序集的O(log n)。
vartec

18
@utdmr:OrderedDict按插入顺序排序,而不是按任意键排序,就像排序的容器一样。
尼尔G

1
@ Hi-Angel不,那不是排序容器的意思。 EG
尼尔摹

1
“分类容器是一种在插入时对元素进行分类的容器”。不完全是:我要说一个有序容器是指其接口具有有效排序(根据任意键)迭代和搜索的容器。您的误解源于您不寻常的定义。
尼尔·G

Answers:


76

对于Guido而言,这是一个有意识的设计决定(他甚至不愿意增加collections模块)。他的目标是在选择应用程序的数据类型时保留“一种显而易见的方式”。

基本概念是,如果用户足够复杂,以至于不能意识到内置类型不是解决其问题的正确解决方案,那么他们还可以找到合适的第三方库。

鉴于list + sorting,list + heapq和list + bisect涵盖了许多本来会依赖于固有排序的数据结构的用例,并且存在像blist这样的包,因此没有很大的动力来增加该空间的复杂性,标准库。

在某些方面,这类似于标准库中没有多维数组的事实,而是将该任务割让给了NumPy员工。


2
谢谢,我一直在寻找这项设计决定背后的动机。这正是我一直在寻找的答案。我最初的直觉不是要这样做,但是这种说法很有说服力。
Neil G

collections.Counter可以用作排序集。虽然可能没有效率。
coderek '17

1
@coderek:collections.Counter未排序,不适合表示已排序的集合。
user2357112支持Monica

但是,至少不应该对内置词典进行排序吗?为了快速访问元素,必须对字典进行排序存储,这对我来说很奇怪,当您遍历字典时,仍然会以某种方式结束未排序的项目。
Hi-Angel

1
@ Hi-Angeldict是一个哈希表。
尼尔·G

80

还有一个python sortedcontainers模块,该模块实现排序列表,字典和集合类型。它与blist非常相似,但是在纯Python中实现,并且在大多数情况下更快

>>> from sortedcontainers import SortedSet
>>> ss = SortedSet([3, 7, 2, 2])
>>> ss
SortedSet([2, 3, 7])

它还具有其他软件包不常见的功能:

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict((num, num) for num in range(100000))
>>> sd.iloc[-5] # Lookup the fifth-to-last key.
99995

免责声明:我是sortedcontainers模块的作者。


1
真好!您可能需要考虑更新文档以指定基础存储是绳索
Neil G

1
@NeilG谢谢!夫妻注意:blist不是用纯Python编写的。排序的集合,列表和字典类型基于blist类型,后者是用C实现的B +树。它更类似于B +树,但只有一层节点。
GrantJ 2014年

3
实际上,这是关于大O误导的一个很好的例子。它可能会减慢大约1万亿个元素,但是大多数人没有TB的内存来担心这一点。我对数十亿个元素进行了测试,它与C实现一样快。通过维护这种简单的基于列表的结构,它也使用更少的内存。
GrantJ 2014年

1
是的,绝对。他们使用相同的参数来证明对字符串(尤其是在编辑器中使用的长字符串)使用这种数据结构是合理的。
尼尔·G

2
无论如何,感谢您撰写本文。如果需要此数据结构,请记住这一点。
尼尔G

11

还有一个blist模块,其中包含一个sortedset数据类型:

sortedset(iterable=(), key=None)

>>> from blist import sortedset
>>> my_set = sortedset([3,7,2,2])
sortedset([2, 3, 7]

5

不完全是一个“排序的容器”,但是您可能会对标准库的bisect模块感兴趣,该模块“提供了对以排序顺序维护列表的支持,而无需在每次插入后对列表进行排序”。


1

heapq标准库中有一个,不是完全排序的,而是一种。还有一个blist包,但是它不在标准库中。


-2

Python列表是有序的。如果对它们进行排序,它们会保持这种状态。在Python 2.7中OrderedDict,添加了一种类型来维护显式排序的字典。

Python还具有集合(成员必须是唯一的集合),但根据定义,它们是无序的。对集合进行排序只会返回list


8
感谢您抽出宝贵的时间回答。OrderedDict按插入顺序排序,而不是按诸如排序容器之类的任意键排序。set也不是排序容器。
尼尔·G

1
btree也许是您要找的东西?stackoverflow.com/questions/628192#628432
詹森主义2011年

谢谢,btree正是我想要的东西。我将使用blist,因为它位于MacPorts中,并且具有许多方便的数据结构。
Neil G
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.