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

递归匹配关联ID,构建规则/量词/转换映射字典的技术求助

问题

现有一个包含rules、quantifiers(示例中对应quant键)、transformations(示例中对应trans键)的字典,各层级对象通过id关联,需完成以下操作:

  • 给定attr = [123, 456],先匹配quantifiers中id在attr内的项,获取其transIds;
  • 匹配transformations中id在transIds内的项,获取其rules列表;
  • 匹配rules中id在上述rules列表内的项,同时从这些项的logic中提取属于quantifiers的metrics值;
  • 最终返回格式为{'rules':[...], 'quantifiers':[...], 'transformations':[...]}的字典。

用户尝试的代码因遍历顺序错误(先遍历rules时,trans和rules列表为空)无法正确捕获关联数据,示例字典与尝试代码如下:

示例字典:

test_dict = {
    'rules': [
        {'id': 123, 'logic': '{"$or":[{"$and":[{"baseOperator":null,"operator":"does_not_contain_ignore_case","operand1":"metrics.123","operand2":"metrics.456"}]}]}'},
        {'id': 589, 'logic': '{"$or":[{"$and":[{"baseOperator":null,"operator":"does_not_contain_ignore_case","operand1":"metrics.123","operand2":0}, {"baseOperator":null,"operator":"does_not_contain_ignore_case","operand1":"metrics.456","operand2":0}]}]}'},
        {'id': 51, 'logic': '{"$or":[{"$and":[{"baseOperator":null,"operator":"does_not_contain_ignore_case","operand1":"metrics.789","operand2":"metrics.1"}]}]}'},
    ],
    'quant': [
        {'id':123, 'transIds': [1, 2, 3], 'qualifiedId': 'metrics.123'},
        {'id':456, 'transIds': [1, 6], 'qualifiedId': 'metrics.456'},
        {'id':789, 'transIds': [9], 'qualifiedId': 'metrics.789'}
    ],
    'trans': [
        {'id':1, 'rules': [123, 120]},
        {'id':6, 'rules':[589, 2]}
    ]
}

尝试的错误代码:

attr = [123, 456]
keys = list(test_dict.keys())
trans = []
rules = []
for iter in range(len(keys)):
    for in_iter in range(len(test_dict[keys[iter]])):
        
        if test_dict[keys[iter]][in_iter].get('id') in attr:
            if test_dict[keys[iter]][in_iter].get('transIds') is not None:
                for J in test_dict[keys[iter]][in_iter].get('transIds'):
                    trans.append(J)
        
        if test_dict[keys[iter]][in_iter].get('id') in trans:
            if test_dict[keys[iter]][in_iter].get('rules') is not None:
                for K in test_dict[keys[iter]][in_iter].get('rules'):
                    rules.append(K)

        if test_dict[keys[iter]][in_iter].get('id') in rules:
            if test_dict[keys[iter]][in_iter].get('logic') is not None:
                print(test_dict[keys[iter]][in_iter].get('logic'))

解决方案

核心问题是原代码乱序遍历所有层级,没有按照需求的依赖顺序执行。正确的做法是按需求步骤依次执行,先获取quantifiers,再推导transformations,最后获取rules并提取metrics。

完整实现代码

import json

def get_associated_data(test_dict, attr):
    # 步骤1:筛选目标quantifiers(对应示例中的quant),收集transIds
    target_quants = [q for q in test_dict['quant'] if q['id'] in attr]
    trans_ids = set()
    for q in target_quants:
        trans_ids.update(q.get('transIds', []))
    
    # 步骤2:筛选目标transformations(对应示例中的trans),收集ruleIds
    target_trans = [t for t in test_dict['trans'] if t['id'] in trans_ids]
    rule_ids = set()
    for t in target_trans:
        rule_ids.update(t.get('rules', []))
    
    # 步骤3:筛选目标rules,同时提取logic中的metrics对应的quantifiers
    target_rules = [r for r in test_dict['rules'] if r['id'] in rule_ids]
    # 建立quant的qualifiedId到对象的映射,方便快速查找
    quant_map = {q['qualifiedId']: q for q in test_dict['quant']}
    # 收集所有从logic中提取到的有效quantifiers
    extracted_quants = set()
    
    for rule in target_rules:
        logic_json = json.loads(rule['logic'])
        # 递归遍历logic结构,提取所有metrics.xxx格式的operand值
        def extract_metrics(obj):
            if isinstance(obj, dict):
                for k, v in obj.items():
                    if k in ['operand1', 'operand2'] and isinstance(v, str) and v.startswith('metrics.'):
                        extracted_quants.add(v)
                    else:
                        extract_metrics(v)
            elif isinstance(obj, list):
                for item in obj:
                    extract_metrics(item)
        extract_metrics(logic_json)
    
    # 把extracted_quants转换成对应的quant对象
    final_quants = [quant_map[q_str] for q_str in extracted_quants if q_str in quant_map]
    # 合并初始的target_quants和提取到的quants,按id去重
    quant_id_set = {q['id'] for q in target_quants + final_quants}
    final_quants = [q for q in test_dict['quant'] if q['id'] in quant_id_set]
    
    # 整理成要求的返回格式
    return {
        'rules': target_rules,
        'quantifiers': final_quants,
        'transformations': target_trans
    }

# 测试调用
attr = [123, 456]
result = get_associated_data(test_dict, attr)
print(json.dumps(result, indent=2))

代码说明

  1. 按依赖顺序执行:严格按照需求步骤依次处理,先获取目标quantifiers,再推导关联的transformations,最后获取rules并提取metrics,避免了原代码乱序遍历导致的空列表问题。
  2. 用集合去重:使用set存储trans_ids和rule_ids,避免重复添加同一id。
  3. 解析JSON逻辑字符串:将logic字段的JSON字符串解析为字典,通过递归遍历提取所有metrics.xxx格式的操作数,再映射到对应的quantifiers对象。
  4. 去重最终quantifiers:合并初始筛选的quantifiers和从logic中提取的quantifiers,按id去重,确保结果无重复项。

运行结果

返回的字典中:

  • rules包含id为123、589的规则
  • transformations包含id为1、6的转换项
  • quantifiers包含id为123、456的量化项(与attr匹配且在logic中出现)

内容的提问来源于stack exchange,提问作者Dollar Tune-bill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:25:17