如何在不执行值的昂贵计算的情况下获取字典的键?
解决方案:不执行昂贵操作获取字典键列表并避免手动维护
下面提供几种易维护、不易出错的方案,按需选择:
方案1:用函数对象实现懒加载
把昂贵操作封装成函数,字典中先存储函数对象而非执行结果,这样定义字典时不会触发昂贵操作,键列表可直接从字典的keys()获取。
def func(): # 将昂贵操作封装为函数,不立即执行 def lazy_op1(): return expensive_operation1() def lazy_op2(): return expensive_operation2() # 字典存储函数对象,而非操作结果 map = { "aaa": lazy_op1, "bbb": lazy_op2 } # 直接获取键列表,完全不触发昂贵操作 key_list = list(map.keys()) # 实际需要使用值时,再调用函数执行 # 例如:result = map["aaa"]() ...
优点:添加新键时,只需在字典中新增"key": func的条目,键列表会自动更新,无需手动维护。
方案2:先定义键列表,动态生成字典
反过来以键列表为核心,维护键与对应操作的映射关系,再动态生成字典。这样添加新键时,只需更新键列表和映射关系,避免两处手动同步的问题。
def func(): # 唯一需要维护的键列表 key_list = ["aaa", "bbb"] # 键与对应昂贵操作的映射 key_op_map = { "aaa": expensive_operation1, "bbb": expensive_operation2 } # 动态生成字典,仅在需要时执行昂贵操作 map = {key: key_op_map[key]() for key in key_list} # 键列表直接使用预先定义的key_list即可 ...
优点:键列表是源数据,所有字典操作基于它生成,不会出现键列表与字典不一致的情况;新增键时只需在key_list和key_op_map中各添加一行,逻辑清晰。
方案3:用类封装懒加载逻辑
如果场景需要更复杂的状态管理,可以用类封装懒加载行为,将键列表和操作映射集中管理,外部只需调用方法获取键或值。
class LazyDict: def __init__(self): # 集中维护键列表 self.keys = ["aaa", "bbb"] # 键与对应昂贵操作的映射 self._operations = { "aaa": expensive_operation1, "bbb": expensive_operation2 } # 存储已执行过的操作结果 self._cached_data = {} def __getitem__(self, key): # 仅在首次访问时执行昂贵操作并缓存结果 if key not in self._cached_data: self._cached_data[key] = self._operations[key]() return self._cached_data[key] def get_keys(self): # 返回键列表的副本,避免外部修改影响内部状态 return self.keys.copy() def func(): lazy_map = LazyDict() # 获取键列表,不触发任何昂贵操作 key_list = lazy_map.get_keys() # 需要值时再访问,自动执行并缓存 # 例如:value = lazy_map["aaa"] ...
优点:封装性强,内部状态统一管理,外部无需关心懒加载细节;新增键时只需修改类中的keys和_operations,维护成本低。
内容的提问来源于stack exchange,提问作者kms333
相关产品推荐
相关产品推荐

