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

Python多键同值字典如何压缩体积且保持单键正常访问?

解答

Python 原生标准库及 collections 模块未提供直接满足该需求的现成数据类型,你可以通过继承 dict 实现自定义类,完全兼容普通字典的访问逻辑,同时支持同值批量更新、导出压缩结构的能力。

实现代码

class GroupedValueDict(dict):
    def __init__(self, data=None):
        super().__init__()
        self._key_map = {}  # 单键到值的映射,保证O(1)访问效率
        self._value_groups = {}  # 值到对应键集合的映射,用于批量更新
        if data:
            # 初始化时自动对同值键分组
            for k, v in data.items():
                self._key_map[k] = v
                if v not in self._value_groups:
                    self._value_groups[v] = set()
                self._value_groups[v].add(k)
    
    def __getitem__(self, key):
        if key not in self._key_map:
            raise KeyError(key)
        return self._key_map[key]
    
    def __setitem__(self, key, value):
        # 键已存在时先从旧值分组中移除
        if key in self._key_map:
            old_val = self._key_map[key]
            self._value_groups[old_val].remove(key)
            if not self._value_groups[old_val]:
                del self._value_groups[old_val]
        # 更新为新的映射关系
        self._key_map[key] = value
        if value not in self._value_groups:
            self._value_groups[value] = set()
        self._value_groups[value].add(key)
    
    def update_group_value(self, old_value, new_value):
        # 批量修改所有对应old_value的键的值
        if old_value not in self._value_groups:
            raise ValueError(f"不存在值为{old_value}的分组")
        if old_value == new_value:
            return
        # 取出关联键集合
        keys = self._value_groups.pop(old_value)
        # 更新单键映射
        for k in keys:
            self._key_map[k] = new_value
        # 合并到新值的分组
        if new_value in self._value_groups:
            self._value_groups[new_value].update(keys)
        else:
            self._value_groups[new_value] = keys
    
    # 导出题目要求的{键元组: 值}压缩结构
    def export_compressed(self):
        return {tuple(keys): v for v, keys in self._value_groups.items()}

使用示例

# 传入原始字典初始化
d = GroupedValueDict({'a': 'X', 'b': 'X', 'c': 'X', 'd': 'X', 'e': 'X', 'f': 'Z'})

# 兼容普通字典的访问方式
print(d['a'] == 'X')  # 输出 True
print(d['f'] == 'Z')  # 输出 True

# 一处修改全量同值生效
d.update_group_value('X', '新的长文本内容')
print(d['a'] == '新的长文本内容')  # 输出 True
print(d['b'] == '新的长文本内容')  # 输出 True
print(d['c'] == '新的长文本内容')  # 输出 True

# 导出压缩结构
compressed = d.export_compressed()
print(compressed)
# 输出:{('a', 'b', 'c', 'd', 'e'): '新的长文本内容', ('f',): 'Z'}

补充说明

  • 如果存储的长文本是可变对象(如列表、自定义类实例),无需调用update_group_value,直接修改值本身就会对所有关联键生效,因为所有键指向的是同一个内存地址的对象。
  • 如需完全兼容原生dict的所有内置方法,可以根据需求补充重写__contains__、keys、values、items等魔术方法,上述示例已经覆盖核心的访问和批量更新需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:06:02