按目录名与文件名多层分组排序Python路径的实现问题
多层路径分组排序解决方案
问题描述
需要对给定的路径列表按以下规则进行嵌套分组排序:
- 一级分组:按路径中的
TENT1/TENT2目录划分 - 二级分组:按文件名前缀(如
metr-ok、weig-ok)划分,无论文件是直接位于TENT目录下还是其下的Job子目录中
原使用groupby结合dirname的代码无法实现预期结构,需求解。
输入路径列表:
paths = [ '/var/lib/conc/states/TENT1/Job1/metr-ok_2022_11_28', '/var/lib/conc/states/TENT1/Job1/metr-ok_2022_11_29', '/var/lib/conc/states/TENT1/Job1/weig-ok_2022_11_28', '/var/lib/conc/states/TENT1/Job1/weig-ok_2022_11_29', '/var/lib/conc/states/TENT1/down-ok_2022_11_27', '/var/lib/conc/states/TENT1/down-ok_2022_11_28', '/var/lib/conc/states/TENT1/serv-ok_2022_11_28', '/var/lib/conc/states/TENT1/serv-ok_2022_11_29', '/var/lib/conc/states/TENT2/Job2/metr-ok_2022_11_28', '/var/lib/conc/states/TENT2/Job2/metr-ok_2022_11_29', '/var/lib/conc/states/TENT2/Job2/weig-ok_2022_11_28', '/var/lib/conc/states/TENT2/Job2/weig-ok_2022_11_29', '/var/lib/conc/states/TENT2/down-ok_2022_11_27', '/var/lib/conc/states/TENT2/down-ok_2022_11_28', '/var/lib/conc/states/TENT2/serv-ok_2022_11_28', '/var/lib/conc/states/TENT2/serv-ok_2022_11_29', ]
预期输出结构:
[ [ [ '/var/lib/conc/states/TENT1/Job1/metr-ok_2022_11_28', '/var/lib/conc/states/TENT1/Job1/metr-ok_2022_11_29' ], [ '/var/lib/conc/states/TENT1/Job1/weig-ok_2022_11_28', '/var/lib/conc/states/TENT1/Job1/weig-ok_2022_11_29' ], [ '/var/lib/conc/states/TENT1/down-ok_2022_11_27', '/var/lib/conc/states/TENT1/down-ok_2022_11_28', ], [ '/var/lib/conc/states/TENT1/serv-ok_2022_11_28', '/var/lib/conc/states/TENT1/serv-ok_2022_11_29' ], ], [ [ '/var/lib/conc/states/TENT2/Job2/metr-ok_2022_11_28', '/var/lib/conc/states/TENT2/Job2/metr-ok_2022_11_29' ], [ '/var/lib/conc/states/TENT2/Job2/weig-ok_2022_11_28', '/var/lib/conc/states/TENT2/Job2/weig-ok_2022_11_29' ], [ '/var/lib/conc/states/TENT2/down-ok_2022_11_27', '/var/lib/conc/states/TENT2/down-ok_2022_11_28', ], [ '/var/lib/conc/states/TENT2/serv-ok_2022_11_28', '/var/lib/conc/states/TENT2/serv-ok_2022_11_29', ], ] ]
原代码问题分析
- 分组键错误:使用
dirname作为分组键只能按文件所在目录分组,无法实现按文件名前缀跨目录分组的需求。 - 未提前排序:
itertools.groupby要求输入序列必须先按分组键排序,否则会将同键但不连续的元素分到不同组。
解决方案代码
from itertools import groupby from os.path import basename def get_tent_group(path): # 提取路径中的TENT1/TENT2作为一级分组键 return path.split('/')[4] def get_file_prefix(path): # 提取文件名前缀(如metr-ok、weig-ok)作为二级分组键 filename = basename(path) return '_'.join(filename.split('_')[:2]) # 先按一级分组键、再按二级分组键排序,确保同组元素连续 sorted_paths = sorted(paths, key=lambda x: (get_tent_group(x), get_file_prefix(x))) # 构建嵌套分组结构 result = [] for _, tent_group in groupby(sorted_paths, key=get_tent_group): inner_groups = [] for _, file_group in groupby(tent_group, key=get_file_prefix): inner_groups.append(list(file_group)) result.append(inner_groups) # 验证输出 print(result)
代码说明
- 分组键定义:
get_tent_group:通过分割路径提取TENT1/TENT2部分作为一级分组依据。get_file_prefix:提取文件名中_前两位(如metr-ok)作为二级分组依据,实现跨目录同前缀文件的分组。
- 排序处理:先按一级键、再按二级键排序,保证
groupby能正确识别连续的同组元素。 - 嵌套分组:先按TENT分组,再在每个TENT组内按文件前缀分组,最终形成预期的三层嵌套列表。
内容的提问来源于stack exchange,提问作者dean89
相关产品推荐
相关产品推荐

