Python有有序集合吗?

738

Python有一个有序字典。那么有没有有序集合呢?


24
相反的情况又如何呢,一袋子东西呢?(无序且不唯一) - wim
27
@wim collections.Counter 是 Python 中的一个“袋子”。 - flornquake
4
如果某个东西被添加了两次怎么办?应该采取什么立场? - McKay
7
如果按照collections.OrderDict的行为来进行,那么它仍然会保持初始添加时的位置。 - wojtow
12
警告:这里有些答案已经过时了。例如,dict现在是按插入顺序排序的(自Python 3.7起保证)。 - Walter Tross
显示剩余6条评论
16个回答

5

正如其他人所说,OrderedDict 的功能是有序集合的超集,但如果你需要一个用于与API交互的集合,并且不需要它是可变的,那么 OrderedDict.keys() 实际上是实现了 abc.collections.Set

import random
from collections import OrderedDict, abc

a = list(range(0, 100))
random.shuffle(a)

# True
a == list(OrderedDict((i, 0) for i in a).keys())

# True
isinstance(OrderedDict().keys(), abc.Set)   
需要注意的是,这种方法有不可变性,并且需要像字典一样建立集合,但它很简单,只使用了内置函数。

2

ParallelRegression包提供了一个setList()有序集合类,该类比基于ActiveState配方的选项更完整。它支持所有可用于列表的方法,如果不是全部,也支持大部分可用于集合的方法。


0

有一个pip库可以做到这一点:

pip install ordered-set

然后你可以使用它:

from ordered_set import OrderedSet

0
只需使用来自pandas的pd.unique - 正好做你需要的事情!
>>> import pandas as pd
>>> pd.unique([3, 1, 4, 5, 2, 2])
array([3, 1, 4, 5, 2])

-3
这个答案是为了完整性而存在的。如果你的集合长度较小,并且你的代码是单线程的,一个列表就可以很好地满足要求,因为它是隐式有序的。
if not new_item in my_list:
    my_list.append(new_item)

如果使用这种方法:
- 要添加或删除一个项目,首先像上面的代码一样检查是否存在。 - 要比较相等性,请使用 `set(my_list)`。
当然,在列表中检查是否存在的复杂度为 O(n),但对于小型列表来说,这可能是可以接受的,尤其是如果不需要高性能。

2
这种方法的主要问题是添加操作的时间复杂度为O(n),也就是说,随着列表规模的增大,速度会变慢。Python内置的集合(set)非常擅长于加快元素的添加速度。但对于简单的用例,它肯定可以胜任! - Draconis
这个答案不应该被删除,因为这种方法对于小型列表来说是可以接受的,而且不需要最佳性能。 - Asclepius
这个答案不应该被删除,因为这种方法在小型列表中的效果是可以接受的,而且不需要最佳性能。 - undefined

-6
对于许多目的,仅调用sorted函数就足够了。例如:
>>> s = set([0, 1, 2, 99, 4, 40, 3, 20, 24, 100, 60])
>>> sorted(s)
[0, 1, 2, 3, 4, 20, 24, 40, 60, 99, 100]

如果您要重复使用此功能,则调用排序函数会产生开销,因此您可能希望保存结果列表,只要您完成了对集合的更改。如果您需要维护唯一元素并进行排序,我同意使用来自collections的OrderedDict和任意值(例如None)的建议。


48
OrderedSet 的目的是能够按照添加到集合中的顺序获取项目。你提供的示例可能称为 SortedSet(排序集)。 - Periodic Maintenance

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接