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

如何高效搜索Python嵌套字典?21000条数据提速方案

优化方案:预构建反向索引

由于你的数据是启动时加载完成、运行期只读的,最有效的优化方式是预构建反向索引表,把每个属性键、属性键值对映射到对应的职业列表,这样搜索时直接通过索引查询,不需要遍历全量21000条数据。

1. 构建两种核心索引

  • 属性存在索引:记录包含某个属性(如crime)的所有职业
  • 属性键值对索引:记录某个属性等于特定值(如crime="high")的所有职业

代码实现

test_data = {
    "hacker": {"crime": "high"},
    "mugger": {"crime": "high", "morals": "low"},
    "shop_owner": {"crime": "high", "morals": "high"},
    "office_drone": {"work_drive": "high", "tolerance": "high"},
    "farmer": {"work_drive": "high"},
}

class OptimizedConditional:
    def __init__(self, data):
        self.dataset = data
        # 预构建索引
        self.attr_exists_index = {}  # key: 属性名, value: 职业列表
        self.attr_value_index = {}   # key: (属性名, 属性值), value: 职业列表
        
        for job, attrs in data.items():
            # 处理属性存在索引
            for attr in attrs:
                if attr not in self.attr_exists_index:
                    self.attr_exists_index[attr] = []
                self.attr_exists_index[attr].append(job)
            # 处理属性键值对索引
            for attr, val in attrs.items():
                key = (attr, val)
                if key not in self.attr_value_index:
                    self.attr_value_index[key] = []
                self.attr_value_index[key].append(job)
    
    def find(self, *required_attrs, **tag_filters):
        # 先处理必填属性的交集
        result_set = None
        if required_attrs:
            try:
                result_set = set(self.attr_exists_index[required_attrs[0]])
                for attr in required_attrs[1:]:
                    result_set.intersection_update(self.attr_exists_index[attr])
            except KeyError:
                # 某个必填属性不存在,直接返回空列表
                return []
        
        # 处理键值对过滤
        if tag_filters:
            filter_sets = []
            for attr, val in tag_filters.items():
                key = (attr, val)
                if key not in self.attr_value_index:
                    return []
                filter_sets.append(set(self.attr_value_index[key]))
            
            # 计算所有过滤条件的交集
            filter_result = set(filter_sets[0])
            for s in filter_sets[1:]:
                filter_result.intersection_update(s)
            
            # 和必填属性的结果取交集
            if result_set is not None:
                result_set.intersection_update(filter_result)
            else:
                result_set = filter_result
        
        # 处理无过滤条件的情况
        if result_set is None:
            return list(self.dataset.keys())
        
        return list(result_set)

# 测试
jobs = OptimizedConditional(test_data)
print(jobs.find(work_drive="high"))
>>> ['office_drone', 'farmer']
print(jobs.find("crime"))
>>> ['hacker', 'mugger', 'shop_owner']
print(jobs.find("crime", "morals"))
>>> ['mugger', 'shop_owner']
print(jobs.find("crime", morals="high"))
>>> ['shop_owner']

2. 效率提升的核心原因

  • 时间复杂度优化:原方法每次搜索是O(N)(N为职业总数),预索引后搜索是O(K)(K为结果集大小),对于21000条数据的场景,多次搜索的效率提升非常显著。
  • 集合操作的底层优化:Python的集合交集操作是C实现的,比手动遍历判断快数倍。
  • 只读数据的优势:索引仅在启动时构建一次,后续搜索直接复用,无额外开销。

3. 额外小优化

  • 提前将职业列表转为集合,进一步加速交集运算。
  • 对不存在的属性/键值对直接返回空列表,避免无效计算。
  • 若后续需要支持模糊搜索,可扩展使用前缀树(Trie)或倒排索引,但当前精确匹配场景下,上述索引已足够。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:20:52