Python中是否存在集合与字典的中间结构?支持带可选值的唯一键
解决方案:自定义混合集合-字典结构处理C预定义宏
哈哈,这个需求太懂了!处理C预定义宏的时候,就是会遇到这种一半有值、一半没值的情况——用字典存None确实看着乱糟糟的,defaultdict又完全不对路子,因为我们是明确要区分“主动添加的无值键”和“未定义的键”。下面给你几个实用的方案:
方案1:自定义封装类(最贴合你的语法期望)
自己写一个小类,内部用字典管理,但对外提供集合+字典的混合接口,甚至可以模拟你想要的{1: 'one', 2, 3}风格输出:
class DefineStore: def __init__(self): self._internal_dict = {} # 用一个独一无二的对象标记无值的宏,避免和用户传入的None/其他值冲突 self._NO_VALUE = object() def add(self, name): """添加无值的宏(对应-DSOMETHING)""" self._internal_dict[name] = self._NO_VALUE def __setitem__(self, name, value): """添加带值的宏(对应-DSOMETHING=FOO)""" self._internal_dict[name] = value def __getitem__(self, name): """获取宏的值:有值返回值,无值返回None,不存在则抛KeyError""" val = self._internal_dict[name] return None if val is self._NO_VALUE else val def __contains__(self, name): """判断宏是否存在""" return name in self._internal_dict def __repr__(self): # 输出你想要的简洁格式 parts = [] for key, val in self._internal_dict.items(): if val is self._NO_VALUE: parts.append(repr(key)) else: parts.append(f"{repr(key)}: {repr(val)}") return "{" + ", ".join(parts) + "}"
用法示例:
macros = DefineStore() macros.add(2) macros.add(3) macros[1] = 'one' print(macros) # 输出 {1: 'one', 2, 3},完美符合你的期望! print(1 in macros) # True print(macros[1]) # 'one' print(macros[2]) # None
方案2:拆分存储(更轻量的实现)
如果不想搞太复杂的类,可以用一个字典存带值的宏,一个集合存无值的宏,对外封装统一接口:
class DefineStore: def __init__(self): self._with_value = {} self._without_value = set() def add(self, name): """添加无值宏""" # 如果之前有值,先移除 self._with_value.pop(name, None) self._without_value.add(name) def __setitem__(self, name, value): """添加带值宏""" # 如果之前是无值,先移除 self._without_value.discard(name) self._with_value[name] = value def __getitem__(self, name): if name in self._with_value: return self._with_value[name] elif name in self._without_value: return None raise KeyError(f"Macro {name} not defined") def __repr__(self): parts = [f"{repr(k)}: {repr(v)}" for k, v in self._with_value.items()] parts.extend([repr(k) for k in self._without_value]) return "{" + ", ".join(parts) + "}"
这种方式内部数据结构更清晰,无值宏直接存在集合里,不用特殊标记,适合对内存占用敏感的场景。
方案3:极简临时方案(快速上手)
如果只是临时用,不想写类,可以用字典+特殊值的方式,比如用...(Ellipsis)表示无值,比None更清晰:
macros = {1: 'one', 2: ..., 3: ...} # 判断逻辑 for key, val in macros.items(): if val is ...: print(f"-D{key}") else: print(f"-D{key}={val}")
这种方式不需要额外代码,但需要团队内部约定好...代表无值,适合小范围快速实现。
内容的提问来源于stack exchange,提问作者Tor Klingberg
相关产品推荐
相关产品推荐

