Does Python have an ordered set?
python有一个有序的字典。一套定购的怎么样?
这有一个有序的集合(可能是新的链接)方法,可以从python 2文档中引用。在PY2.6或更高版本以及3.0或更高版本上运行,无需任何修改。接口几乎与正常设置完全相同,只是初始化应该用一个列表来完成。
1 | OrderedSet([1, 2, 3]) |
这是一个可变集,因此
1 2 3 4 5 6 7 8 9 | @staticmethod def union(*sets): union = OrderedSet() union.union(*sets) return union def union(self, *sets): for set in sets: self |= set |
号
有序集在功能上是有序字典的特例。
字典的键是唯一的。因此,如果忽略了有序字典中的值(例如,通过给它们指定
从python 3.1开始,有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import collections class OrderedSet(collections.OrderedDict, collections.MutableSet): def update(self, *args, **kwargs): if kwargs: raise TypeError("update() takes no keyword arguments") for s in args: for e in s: self.add(e) def add(self, elem): self[elem] = None def discard(self, elem): self.pop(elem, None) def __le__(self, other): return all(e in other for e in self) def __lt__(self, other): return self <= other and self != other def __ge__(self, other): return all(e in self for e in other) def __gt__(self, other): return self >= other and self != other def __repr__(self): return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys()))) def __str__(self): return '{%s}' % (', '.join(map(repr, self.keys()))) difference = property(lambda self: self.__sub__) difference_update = property(lambda self: self.__isub__) intersection = property(lambda self: self.__and__) intersection_update = property(lambda self: self.__iand__) issubset = property(lambda self: self.__le__) issuperset = property(lambda self: self.__ge__) symmetric_difference = property(lambda self: self.__xor__) symmetric_difference_update = property(lambda self: self.__ixor__) union = property(lambda self: self.__or__) |
我可以为您做一个比有序集更好的:Boltons有一个纯python,2/3兼容的
只需
1 2 3 4 5 6 7 8 9 10 11 | >>> from boltons.setutils import IndexedSet >>> x = IndexedSet(list(range(4)) + list(range(8))) >>> x IndexedSet([0, 1, 2, 3, 4, 5, 6, 7]) >>> x - set(range(2)) IndexedSet([2, 3, 4, 5, 6, 7]) >>> x[-1] 7 >>> fcr = IndexedSet('freecreditreport.com') >>> ''.join(fcr[:fcr.index('.')]) 'frecditpo' |
。
一切都是独一无二的,井然有序。完全公开:我写了
Pypi上的实现
虽然其他人已经指出,在python中还没有插入顺序保留集的内置实现,但我觉得这个问题缺少一个说明在pypi上可以找到什么的答案。
据我所知,目前有:
- 有序集
- OSET
这两种实现都基于RaymondHettinger发布给ActiveState的配方,其他答案也提到了这一点。我已经检查了两个并确定了以下内容
关键区别:- 有序集(1.1版)
- 优势:O(1)用于按索引查找(如
my_set[5] ) - 缺点:
remove(item) 未实施
- 优势:O(1)用于按索引查找(如
- OSET(0.1.3版)
- 优势:o(1)用于
remove(item) 。 - 缺点:按索引查找显然是O(N)
- 优势:o(1)用于
两种实现都有用于
不幸的是,两种实现都没有基于方法的集合操作,比如
我第一次使用有序的集合,直到我第一次使用
如果您知道Pypi上的其他实现,请在注释中告诉我。
答案是否定的,但是您可以使用Python标准库中的
更新:从python 3.7(和cpython 3.6)开始,标准的
下面是一个示例,说明如何使用
1 2 3 4 | >>> keywords = ['foo', 'bar', 'bar', 'foo', 'baz', 'foo'] >>> list(dict.fromkeys(keywords).keys()) ['foo', 'bar', 'baz'] |
。
如果您使用排序集来维护排序顺序,那么考虑使用来自PYPI的排序集实现。SortedContainers模块仅为此目的提供SortedSet。一些好处:纯Python、快速的as-c实现、100%的单元测试覆盖率、数小时的压力测试。
使用pip从pypi安装很容易:
1 | pip install sortedcontainers |
请注意,如果不能执行
安装后,您可以简单地:
1 2 | from sortedcontainers import SortedSet help(SortedSet) |
号
SortedContainers模块还与几个可选实现保持性能比较。
对于询问关于python的bag数据类型的注释,也可以使用sortedList数据类型来高效地实现bag。
如果您已经在代码中使用了panda,那么它的
官方图书馆里没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | DataStructure = { 'Collections': { 'Map': [ ('dict', 'OrderDict', 'defaultdict'), ('chainmap', 'types.MappingProxyType') ], 'Set': [('set', 'frozenset'), {'multiset': 'collection.Counter'}] }, 'Sequence': { 'Basic': ['list', 'tuple', 'iterator'] }, 'Algorithm': { 'Priority': ['heapq', 'queue.PriorityQueue'], 'Queue': ['queue.Queue', 'multiprocessing.Queue'], 'Stack': ['collection.deque', 'queue.LifeQueue'] }, 'text_sequence': ['str', 'byte', 'bytearray'] } |
游戏稍微晚了一点,但我已经写了一个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> from collections_extended import setlist >>> sl = setlist('abracadabra') >>> sl setlist(('a', 'b', 'r', 'c', 'd')) >>> sl[3] 'c' >>> sl[-1] 'd' >>> 'r' in sl # testing for inclusion is fast True >>> sl.index('d') # so is finding the index of an element 4 >>> sl.insert(1, 'd') # inserting an element already in raises a ValueError ValueError >>> sl.index('d') 4 |
github:https://github.com/mlenzen/collections-extended
文档:http://collections-extended.lenzm.net/en/latest/
pypi:https://pypi.python.org/pypi/collections-extended
对于许多目的来说,简单地调用sorted就足够了。例如
1 2 3 | >>> 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] |
。
如果您要重复使用它,那么调用排序函数会产生开销,因此您可能希望保存结果列表,只要您更改了集合。如果您需要维护唯一的元素并对其进行排序,我同意从具有任意值(如none)的集合中使用ordereddict的建议。
ParallelRegression包提供了一个setList()顺序集类,它比基于ActiveState配方的选项更完整。它支持所有可用于列表的方法,如果不是所有方法都可用于集合,则支持大多数方法。
所以我也有一个小列表,很明显我有可能引入非唯一的值。
我搜索了某种独特列表的存在性,但是后来意识到在添加元素之前测试元素的存在性是很好的。
1 2 | if(not new_element in my_list): my_list.append(new_element) |
。
我不知道这种简单的方法是否值得注意,但它解决了我的问题。
我相信有四种订购方式:
我相信collections.ordereddict会让你4。或者,您可以删除一个键并重新添加它,用于3。
对于1,您可能应该查看红黑树或Treap:
- http://pypi.python.org/pypi/bintrees/0.3.0
- http://pypi.python.org/pypi/rbtree/
- http://stromberg.dnsalias.org/~dstromberg/treap/
红黑树在操作时间上的可变性很低(因此对于交互应用程序来说可能更好),但其速度不如平均水平上的Treaps(对于批处理来说可能更好——Treaps不会自我重组,通常会使其快速,但当它们进行重组时,可能需要相当长的时间)。
这两种方法都是建立的数据结构,具有多种语言的实现。