You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python能否实现兼具三大特性的InfiniteDefaultRevisionDictionary?

可以实现兼具三大特性的 InfiniteDefaultRevisionDictionary

核心思路拆解

要同时实现修改序排序、默认值支持、无限嵌套访问三大特性,我们需要:

  • 多排序策略适配:维护插入顺序和修改顺序两个列表,初始化时指定规则,重写字典迭代方法返回对应顺序的键值对
  • 嵌套赋值自动创建:通过代理对象处理链式赋值场景,自动生成中间层级的字典实例
  • 读取默认值返回:访问不存在的键时返回指定默认值,同时不影响后续赋值操作

完整实现代码

from collections.abc import MutableMapping
from typing import Any, Literal, Optional

class InfiniteDefaultRevisionDictionary(MutableMapping):
    def __init__(
        self,
        default_value: Any = 0,
        order: Literal['insert', 'key', 'revision'] = 'revision',
        data: Optional[dict] = None
    ):
        self._store = dict(data or {})
        self._default = default_value
        self._order = order
        # 维护插入顺序和修改顺序的独立列表
        self._insert_order = list(self._store.keys())
        self._revision_order = list(self._store.keys())

    def _update_revision_order(self, key: Any):
        """更新修改顺序:将操作的键移到列表末尾"""
        if key in self._revision_order:
            self._revision_order.remove(key)
        self._revision_order.append(key)

    def __getitem__(self, key: Any) -> Any:
        if key not in self._store:
            # 代理对象:读取返回默认值,赋值自动创建嵌套节点
            class _DefaultProxy:
                def __init__(self, parent, key):
                    self.parent = parent
                    self.key = key

                def __getitem__(self, subkey: Any) -> Any:
                    return self.parent._default

                def __setitem__(self, subkey: Any, value: Any):
                    # 创建当前层级的字典实例
                    self.parent._store[self.key] = InfiniteDefaultRevisionDictionary(
                        default_value=self.parent._default,
                        order=self.parent._order
                    )
                    # 完成子键赋值
                    self.parent._store[self.key][subkey] = value
                    self.parent._update_revision_order(self.key)

                def __repr__(self):
                    return repr(self.parent._default)

            return _DefaultProxy(self, key)
        return self._store[key]

    def __setitem__(self, key: Any, value: Any):
        # 普通字典自动转为当前类实例,保持嵌套特性
        if isinstance(value, dict) and not isinstance(value, InfiniteDefaultRevisionDictionary):
            value = InfiniteDefaultRevisionDictionary(
                default_value=self._default,
                order=self._order,
                data=value
            )
        is_new_key = key not in self._store
        self._store[key] = value
        # 更新插入顺序(仅新增键时)
        if is_new_key:
            self._insert_order.append(key)
        # 更新修改顺序(新增/修改都触发)
        self._update_revision_order(key)

    def __delitem__(self, key: Any):
        del self._store[key]
        if key in self._insert_order:
            self._insert_order.remove(key)
        if key in self._revision_order:
            self._revision_order.remove(key)

    def __iter__(self):
        if self._order == 'insert':
            yield from self._insert_order
        elif self._order == 'revision':
            yield from self._revision_order
        elif self._order == 'key':
            yield from sorted(self._store.keys())

    def __len__(self) -> int:
        return len(self._store)

    def __repr__(self) -> str:
        items = ', '.join([f"{repr(k)}: {repr(v)}" for k, v in self.items()])
        return f"{self.__class__.__name__}({{{items}}})"

    # 重写标准字典方法,确保顺序一致性
    def keys(self):
        return list(self.__iter__())

    def items(self):
        return [(k, self._store[k]) for k in self.__iter__()]

    def values(self):
        return [self._store[k] for k in self.__iter__()]

使用示例与特性验证

1. 基础场景(默认值0+修改序排序)

# 创建实例
dd = InfiniteDefaultRevisionDictionary(default_value=0, order='revision')

# 链式读取不存在的键,返回默认值
print(dd['a']['b']['c'])  # 输出: 0

# 链式赋值,自动创建中间节点
dd['a']['b']['c'] = 5
print(dd['a']['b']['c'])  # 输出: 5
print(dd['a'])  # 输出: InfiniteDefaultRevisionDictionary({'b': InfiniteDefaultRevisionDictionary({'c': 5})})

# 修改已有键,验证修改序更新
dd['x'] = 10
dd['a'] = 'updated'
print(list(dd.keys()))  # 输出: ['x', 'a'](最后修改的键排在末尾)

2. 切换排序策略

  • 插入序:键顺序严格按照首次插入顺序排列
    dd = InfiniteDefaultRevisionDictionary(order='insert')
    dd['z'] = 3
    dd['a'] = 1
    dd['z'] = 4  # 修改已有键不改变插入顺序
    print(list(dd.keys()))  # 输出: ['z', 'a']
    
  • 键序:键按照自然排序规则排列
    dd = InfiniteDefaultRevisionDictionary(order='key', data={'z':3, 'a':1, 'm':2})
    print(list(dd.keys()))  # 输出: ['a', 'm', 'z']
    

3. 自定义默认值

# 默认值为空列表
dd = InfiniteDefaultRevisionDictionary(default_value=[])
print(dd['empty_list'])  # 输出: []
dd['empty_list'].append(1)
print(dd['empty_list'])  # 输出: [1]

特性说明

  • 继承自MutableMapping,完全兼容标准字典的所有操作(update/pop/clear等)
  • 修改序覆盖新增、修改、删除三种场景,确保排序准确
  • 代理对象机制完美区分读取/赋值行为:读取返回默认值,赋值自动创建嵌套节点

内容的提问来源于stack exchange,提问作者xuancong84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:30:56