Python python 如何继承 set,定义一个有序的,无重复的 set 子类?

醋精测试媛 · 2021年03月24日 · 最后由 醋精测试媛 回复于 2021年03月25日 · 4768 次阅读

类似 Java 的TreeSet(与 HashSet 不同的是,TreeSet 具有排序功能,分为自然排序 (123456) 和自定义排序两类,默认是自然排序;在程序中,我们可以按照任意顺序将元素插入到集合中,等到遍历时 TreeSet 会按照一定顺序输出 -- 倒序或者升序 [https://www.jianshu.com/p/d6cff3517688]), python 继承 set 类,拥有 set 的功能,但是这个 set 是有序的,在初始化的时候可以将顺序的规则规定好。

比如:

>>>set = OrderedSet((2, 1, 5, 4, 5))
>>>{1, 2, 4, 5}
>>>set = OrderedSet((2, 1, 5, 4, 5), key=lambda x: x* -1)
>>>{5, 4, 2, 1}

自己试了一下,发现实例化之后输出是 None,百度了也没有看到相似的案例,请教大家怎么实现。

共收到 14 条回复 时间 点赞

继承 list 重写添加方法 加之前先查,找得到就替换,找不到就添加

你好,想问问 ui 自动化相关的内容,

cheunghr 回复

1.试过重写添加方法,但是,因为是内置函数,list 的属性被封装起来了(可能都是私有的了),这种情况下应该怎么做?
2.找得到什么就替换?

回复

可以开一个帖子问

用字典的 key,也可以满足有序无重复

但是必须是 set 的形式

17楼 已删除
  • c 实现的 list ,dict 不是用来继承使用的,如果要修改,请使用 collections.abc 下的那些。 官方没提供默认的 OrderSet, 想必这是个没多少人需要的需求 。应该实现起来比较麻烦,我是不会 (只搞过 UserList)
  • 我能想到的也是 OrderDict 的键,但不知道它提供的 api 和 Set 相差多少。至于贴主说的必须是 Set 的形式,我只能觉得你太那啥了,Python 可是 白鹅类型和鸭子类型,谁会在乎到底是个什么类型呢

《流畅的 Python》作者写道:“在 set 加入 Python 之前,我们就是把字典加上无意义的值当作集合来用的。”

18楼 已删除

有序一般是指集合中数据保留插入的顺序,另一种说法是排序。
刚写了一堆才想起来 set 是支持 sorted 排序的,那这里有啥问题呢,至于例子中的{1,2,4,5}, {5,4,2,1}是相等的。
如果想支持自定义排序:

class OrderSet:
    def __init__(self, source_set, key=None):
        self._set = source_set
        self.key = key

    def __getitem__(self, position):
        _set = sorted(self._set, key=self.key)
        return _set.__getitem__(position)

    def add(self, item):
        self._set.add(item)
set1 = {'a', 'bbb', 'cc', 'dddd'}
test_set = OrderSet(set1, key=len)
test_set.add('e')
for each in test_set:
    print(each)  # a,e,cc,bbb,dddd
hellohell 回复

我是需要把一段 java 的代码转为 python ,里面用到了 TreeSet 和 TreeMap, TreeSet 确实必须要是集合的形式,list 也可以,但不能是字典吧。

意思是至少是一个集合不是 map?

20楼 已删除

谢谢,可以获得一些启发

class TreeMap:
    def __init__(self, source_dict=None):
        self._dict = dict() if source_dict is None else source_dict
        self._sorted_dict = self._sort()

    def _sort(self):
        _sorted_dict = OrderedDict()
        _sorted_keys = list()
        for _key in self._dict.keys():
            bisect.insort(_sorted_keys, _key)
        for _sorted_key in _sorted_keys:
            _sorted_dict[_sorted_key] = self._dict[_sorted_key]
        return _sorted_dict

    def __getitem__(self, index):
        length = self.__len__()
        if index >= length:
            raise StopIteration
        _sorted_dict = self._sorted_dict.copy()
        try:
            for i in range(length):
                item = _sorted_dict.popitem(last=False)
                if i == index:
                    return item
        except KeyError:
            raise

    def __setitem__(self, key, value):
        self._dict[key] = value
        self._sorted_dict = self._sort()

    def __len__(self):
        return len(self._sorted_dict)

    def __str__(self):
        self._sorted_dict = self._sort()
        return str(dict(self._sorted_dict))

    def add(self, key, value):
        self.__setitem__(key, value)

    def get(self, key):
        return self._sorted_dict.get(key)

    def items(self):
        return self._sorted_dict.items()
醋精测试媛 关闭了讨论 03月25日 21:20
醋精测试媛 python 的类的特性:描述符 中提及了此贴 03月31日 17:11
醋精测试媛 python 的类的特性:描述符 中提及了此贴 03月31日 17:11
醋精测试媛 python 的类的特性:描述符 中提及了此贴 03月31日 17:11
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册