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

Python实现下划线分隔列表按规则截取去重的算法求助

列表路径解析Python算法实现

需求背景

需要对以下划线分割的路径字符串列表做规则提取,原始待处理列表如下:

raw_list = ['PPPP_YYYY_ZZZZ_XXXX', 'PPPP_TOTO_TATA_TITI_TUTU', 'PPPP_TOTO_MMMM_TITI_TUTU', 'PPPP_TOTO_EHEH_TITI_TUTU', 'PPPP_TOTO_EHEH_OOOO_AAAAA', 'PPPP_TOTO_EHEH_IIII_SSSS_RRRR']

提取规则

  • 默认提取每个元素按下划线分割的最后2段,格式为PARENT_CHILD,例如元素PPPP_TOTO_TATA_TITI_TUTU初始提取结果为TITI_TUTU
  • 若提取结果存在重复,则所有重复项同步向上多取1段(加入GRANDPARENT层级),重复该操作直到所有提取结果无重复
  • 若某条路径向上取段后引入公共前缀节点(例如EHEH),则所有包含该前缀节点的同分支路径,提取结果需统一带上该前缀节点,例如原本OOOO_AAAAA需调整为EHEH_OOOO_AAAAA

期望输出

['ZZZZ_XXXX', 'TATA_TITI_TUTU', 'MMMM_TITI_TUTU', 'EHEH_TITI_TUTU', 'EHEH_OOOO_AAAAA', 'EHEH_IIII_SSSS_RRRR']

原有代码问题

初始实现代码如下:

json_paths = ['PPPP_YYYY_ZZZZ_XXXX', 'PPPP_TOTO_TATA_TITI_TUTU', 
'PPPP_TOTO_EHEH_TITI_TUTU', 'PPPP_TOTO_MMMM_TITI_TUTU', 'PPPP_TOTO_EHEH_OOOO_AAAAA']

cols_name = []
for path in json_paths:
    acc=2
    col_name = '_'.join(path.split('_')[-acc:])
    tmp = cols_name
    while col_name in tmp:
        acc += 1
        idx = tmp.index(col_name)
        cols_name[idx] = '_'.join(json_paths[idx].split('_')[-acc:])
        col_name = '_'.join(path.split('_')[-acc:])
        tmp = ['_'.join(item.split('_')[-acc:]) for item in json_paths].pop()
    cols_name.append(col_name)
    print(cols_name.index(col_name), col_name)

cols_name

原有代码存在3个核心问题:

  • 未实现规则3要求的公共前缀节点统一追加逻辑,会导致同分支路径前缀缺失
  • 临时列表tmp赋值错误,pop()方法仅返回列表最后一个元素,无法用于全量重复校验
  • 仅调整当前重复项的提取长度,未同步更新关联路径的提取段数,结果不符合规则要求

修正后完整实现

def parse_path_list(raw_paths):
    # 预拆分所有路径为段列表
    path_parts = [p.split('_') for p in raw_paths]
    path_count = len(path_parts)
    # 初始化每个路径默认提取尾部2段
    acc_list = [2] * path_count
    
    def get_extract(acc, parts):
        # 兼容提取长度超过路径总段数的边界情况
        valid_acc = min(acc, len(parts))
        return '_'.join(parts[-valid_acc:])
    
    # 循环迭代调整直到所有结果符合规则
    while True:
        changed = False
        # 获取当前所有路径的提取结果
        current_extracts = [get_extract(acc_list[i], path_parts[i]) for i in range(path_count)]
        # 定位所有重复的提取值
        seen = {}
        dup_values = set()
        for idx, ext in enumerate(current_extracts):
            if ext in seen:
                dup_values.add(ext)
            else:
                seen[ext] = idx
        # 处理重复项:所有重复项提取长度+1
        for val in dup_values:
            for idx in range(path_count):
                if current_extracts[idx] == val:
                    if acc_list[idx] < len(path_parts[idx]):
                        acc_list[idx] += 1
                        changed = True
                        # 拿到本次新增的前缀节点和对应层级位置
                        new_prefix_pos = len(path_parts[idx]) - acc_list[idx]
                        new_prefix_node = path_parts[idx][new_prefix_pos]
                        # 同步处理公共前缀:所有同分支路径统一带上该前缀
                        for other_idx in range(path_count):
                            if other_idx == idx:
                                continue
                            other_parts = path_parts[other_idx]
                            other_len = len(other_parts)
                            # 校验其他路径相同层级是否为同一公共前缀节点
                            if new_prefix_pos < other_len and other_parts[new_prefix_pos] == new_prefix_node:
                                required_acc = other_len - new_prefix_pos
                                if acc_list[other_idx] < required_acc:
                                    acc_list[other_idx] = required_acc
                                    changed = True
        if not changed:
            break
    # 生成最终结果
    return [get_extract(acc_list[i], path_parts[i]) for i in range(path_count)]

# 功能测试
if __name__ == "__main__":
    test_list = ['PPPP_YYYY_ZZZZ_XXXX', 'PPPP_TOTO_TATA_TITI_TUTU', 'PPPP_TOTO_MMMM_TITI_TUTU', 'PPPP_TOTO_EHEH_TITI_TUTU', 'PPPP_TOTO_EHEH_OOOO_AAAAA', 'PPPP_TOTO_EHEH_IIII_SSSS_RRRR']
    result = parse_path_list(test_list)
    print(result)

运行代码后输出结果与期望完全一致:

['ZZZZ_XXXX', 'TATA_TITI_TUTU', 'MMMM_TITI_TUTU', 'EHEH_TITI_TUTU', 'EHEH_OOOO_AAAAA', 'EHEH_IIII_SSSS_RRRR']

逻辑说明:通过维护每个路径的提取长度列表,循环处理重复值,每次给重复项增加提取长度时,自动校验同层级相同前缀的其他路径,同步更新这些路径的提取长度,直到没有任何调整、所有结果满足规则要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:42:16