在数学中,有集合和全序集(oset)。
- set:一个无序的唯一元素容器(已实现)
- oset:一个有序的唯一元素容器(未实现)
在Python中,只直接实现了集合。我们可以使用常规字典键(3.7+)来模拟oset。
要求
a = [1, 2, 20, 6, 210, 2, 1]
b = {2, 6}
代码
oset = dict.fromkeys(a).keys()
演示
副本被移除,插入顺序保留。
list(oset)
在字典的键上执行类似集合的操作。
oset - b
# {1, 20, 210}
oset | b
# {1, 2, 5, 6, 20, 210}
oset & b
# {2, 6}
oset ^ b
# {1, 5, 20, 210}
详情
注:无序结构并不意味着没有有序元素。相反,维护的顺序不能得到保证。例如:
assert {1, 2, 3} == {2, 3, 1}
assert [1, 2, 3] != [2, 3, 1] # lists (order is guaranteed)
有人可能会发现,列表和多重集合(mset)是两个更加迷人的数学数据结构:
- 列表:一个允许复制的有序元素容器(已实现)
- mset:一个允许复制的无序元素容器(未实现)*
摘要
Container | Ordered | Unique | Implemented
----------|---------|--------|------------
set | n | y | y
oset | y | y | n
list | y | n | y
mset | n | n | n*
*使用类似字典的映射 collections.Counter()
可以间接模拟多重集合,其中存储了元素的重复次数(计数)。
unique = list(dict.fromkeys([1, 2, 1]).keys())
可以去除列表中的重复项。这种方法可行是因为现在的字典会保留插入顺序。 - user3064538