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

如何筛选Python列表中各文件夹下路径最短的文件对象

筛选每个文件夹分支下路径最短的文件

我有如下数据:

import datetime
data = [{'name': 'root/folder1/f1/s1.csv' , 'last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)},
        {'name': 'root/folder2/f2/s2/file.csv', 'last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)}, 
        {'name': 'root/folder2/f_1/f_2/f_3/file.csv', 'last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)},
        {'name': 'root/folder2/f_1/f_2/f_3/f_4/f_5/file.csv','last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)}, 
        {'name': 'root/folder2/f3/s3/file.csv', 'last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)},
        {'name': 'root/folder3/f3/s3/s4/file4.csv','last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)},
        {'name' : 'root/folder3/f3/s3/s4/s5/s6/file4.csv','last_modified': datetime.datetime(2022, 8, 4, 18, 43, 13)}
       ]

我需要筛选出每个文件夹分支下路径最短的文件,规则如下:

  • folder1中仅有一个文件,直接保留
  • folder2中,root/folder2/f_1/f_2/f_3/file.csv和root/folder2/f_1/f_2/f_3/f_4/f_5/file.csv属于同分支路径,保留路径更短的前者;root/folder2/f3/s3/file.csv是独立路径,直接保留
  • folder3同理保留路径最短的root/folder3/f3/s3/s4/file4.csv

预期输出

data = [{'name': 'root/folder1/f1/s1.csv'},
        {'name': 'root/folder2/f2/s2/file.csv'}, 
        {'name': 'root/folder2/f_1/f_2/f_3/file.csv'},
        {'name': 'root/folder2/f3/s3/file.csv'},
        {'name': 'root/folder3/f3/s3/s4/file4.csv'}
       ]

当前尝试

我试过通过统计路径斜杠数量筛选最短路径,但不知道怎么针对每个子文件夹分支判断,代码如下:

import os
data_dict = {}
for item in data:
    dir = os.path.dirname(item['name'])
    if dir not in data_dict:
        item['count'] = 1
        data_dict[dir] = item
    else:
        count = data_dic[dir]['count'] + 1
        if item['last_modified'] > data_dict[dir]['last_modified']:
            data_dict[dir] = item
        data_dic[dir]['count'] = count

result = list(data_dict.values())

解决方案

核心逻辑是优先保留短路径,同时排除所有属于已保留路径子目录的长路径。具体实现步骤:

  1. 按路径分割后的长度排序,短路径优先处理,确保先保留分支里最短的路径
  2. 维护已保留路径列表,每次处理新路径时,判断它是否是已保留路径的子目录,或者已保留路径是否是它的子目录,据此决定保留或替换

代码实现:

import os

# 按路径长度从小到大排序,短路径先处理
sorted_data = sorted(data, key=lambda x: len(x['name'].split('/')))

kept_paths = []

for item in sorted_data:
    current_path = item['name']
    need_keep = True
    to_remove = None
    
    # 检查当前路径与已保留路径的关系
    for idx, kept in enumerate(kept_paths):
        common_prefix = os.path.commonprefix([current_path, kept])
        if common_prefix == kept:
            # 当前路径是已保留路径的子目录,跳过
            need_keep = False
            break
        elif common_prefix == current_path:
            # 已保留路径是当前路径的子目录,需要移除长路径
            to_remove = idx
            break
    
    if to_remove is not None:
        del kept_paths[to_remove]
    if need_keep:
        kept_paths.append(current_path)

# 转换为预期的输出格式
result = [{'name': path} for path in kept_paths]

print(result)

代码说明

  • 排序处理:短路径优先进入判断,确保分支里最短的路径先被保留,后续长路径如果属于该分支会直接被排除
  • 路径关系判断:用os.path.commonprefix获取两个路径的公共前缀,以此判断是否存在子目录关系
  • 动态维护保留列表:如果发现已保留的路径是当前路径的子目录,就移除长路径,替换为更短的当前路径

运行后即可得到符合要求的筛选结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:24:29