前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >具有列表功能的有序字典实现 ListOrderedDict

具有列表功能的有序字典实现 ListOrderedDict

作者头像
为为为什么
发布2022-08-06 14:03:04
8530
发布2022-08-06 14:03:04
举报
文章被收录于专栏:又见苍岚又见苍岚

字典和列表都是python中常用的数据结构,各自有各自的优点,但有没有可以结合他们优点的数据结构呢,本文初步实现了具有列表功能的有序字典, 取名 ListOrderedDict。

背景

在python编程中,遇到了字典需要有序的情况,可以使用 collections 库中的 OrderedDict,在保持字典功能的同时使得其元素保持输入顺序;

但在此基础上又需要他拥有列表的性质:

  • 按序号索引
  • 切片提取数据
  • append 和 pop 操作

这就得自己开发了

ListOrderedDict 实现

代码语言:javascript
复制
class ListOrderedDict(OrderedDict):
    def __getitem__(self, key):
        if is_integer(key):
            key = list(self.keys())[key]
        elif isinstance(key, slice):
            slicedkeys = list(self.keys())[key]
            lod_obj = type(self)()
            for slicedkey in slicedkeys:
                lod_obj[slicedkey] = self[slicedkey]
            return lod_obj
        return super().__getitem__(key)

    def append(self, key, value):
        if is_integer(key):
            raise RuntimeError(f" integer key is not allowed in ListOrderedDict {key}.")
        assert key not in self, f"cannot add existed key. {key}"
        self[key] = value
    
    def __setitem__(self, key, value):
        'od.__setitem__(i, y) <==> od[i]=y'
        # Setting a new item creates a new link at the end of the linked list,
        # and the inherited dictionary is updated with the new key/value pair.
        if is_integer(key):
            raise RuntimeError(f" integer key is not allowed in ListOrderedDict {key}.")
        else:
            return super().__setitem__(key, value)

    def __delitem__(self, key):
        'od.__delitem__(y) <==> del od[y]'
        # Deleting an existing item uses self.__map to find the link which gets
        # removed by updating the links in the predecessor and successor nodes.
        if is_integer(key):
            key = list(self.keys())[key]

        return super().__delitem__(key)

    def move_to_end(self, key, last=True):
        '''Move an existing element to the end (or beginning if last is false).

        Raise KeyError if the element does not exist.
        '''
        if is_integer(key):
            key = list(self.keys())[key]

        return super().move_to_end(key, last)

    def __repr__(self):
        'od.__repr__() <==> repr(od)'
        if not self:
            return '%s()' % (self.__class__.__name__,)
        return '%s(%r)' % (self.__class__.__name__, list(self.items()))

    def pop(self, key=-1):
        '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
        value.  If key is not found, d is returned if given, otherwise KeyError
        is raised.
        '''
        if is_integer(key):
            if len(list(self.keys())) == 0:
                print(f"pop a None from an empty ListOrderedDict.")
                return None
            key = list(self.keys())[key]
        return super().pop(key)

    def setdefault(self, key, default=None):
        '''Insert key with a value of default if key is not in the dictionary.

        Return the value for key if key is in the dictionary, else default.
        '''
        if is_integer(key):
            key = list(self.keys())[key]
        return super().setdefault(key, default)

初步实现
  • 按整数下标提取元素
  • 切片
  • append
  • pop
  • 其他有序字典操作
使用

功能集成在了我的常用库 mtutils 中,可以pip直接安装

代码语言:javascript
复制
pip install mtutils

之后直接引用

代码语言:javascript
复制
from mtutils import ListOrderedDict
注意
  • 为了保持几种特性,牺牲了整数作为字典 key 的能力
  • 有问题欢迎随时交流
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年11月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • ListOrderedDict 实现
    • 初步实现
      • 使用
        • 注意
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档