首页 > 解决方案 > 在python中按扩展名对文件路径进行排序

问题描述

我想以 .log 应该是第一个文件并且 .gz 文件应该按降序排列的方式对这个列表进行排序

my_list = [
     '/abc/a.log.1.gz',
     '/abc/a.log',
     '/abc/a.log.gz',
     '/abc/a.log.30.gz',
     '/abc/a.log.2.gz',
     '/abc/a.log.5.gz',
     '/abc/a.log.3.gz',
     '/abc/a.log.6.gz',
     '/abc/a.log.4.gz',
     '/abc/a.log.12.gz',
     '/abc/a.log.10.gz',
     '/abc/a.log.8.gz',
     '/abc/a.log.14.gz',
     '/abc/a.log.29.gz'
]

预期结果:

my_list = ['/abc/a.log',
        '/abc/a.log.gz',
        '/abc/a.log.30.gz',
        '/abc/a.log.29.gz',
        '/abc/a.log.29.gz',
        '/abc/a.log.14.gz',
        '/abc/a.log.12.gz',
        '/abc/a.log.10.gz',
        '/abc/a.log.8.gz',
        '/abc/a.log.6.gz',
        '/abc/a.log.5.gz',
        '/abc/a.log.4.gz',
        '/abc/a.log.3.gz',
        '/abc/a.log.2.gz'
        '/abc/a.log.1.gz']

我的解决方案:导入操作系统

def get_sort_keys(filepath):
    split_file_path = os.path.splitext(filepath)
    sort_key = (split_file_path[1], *os.path.splitext(split_file_path[0]))
    return (sort_key[0], sort_key[1], int(sort_key[2].strip(".")) if sort_key[2] else 0)

print(sorted(my_list, key=get_sort_keys, reverse=True))

得到错误:

ValueError: invalid literal for int() with base 10: 'log'

标签: pythonlistsorting

解决方案


您可以使用sorted一个自定义函数来执行一些除试之外的检查。

def try_convert(x):
    y = x.rsplit('.', 2)[-2]
    return ('log' not in x, int(y) if y.isdigit() else float('inf'), x)

sorted(my_list, key=try_convert, reverse=True)

['/abc/a.log.gz',
 '/abc/a.log',
 '/abc/a.log.30.gz',
 '/abc/a.log.29.gz',
 '/abc/a.log.14.gz',
 '/abc/a.log.12.gz',
 '/abc/a.log.10.gz',
 '/abc/a.log.8.gz',
 '/abc/a.log.6.gz',
 '/abc/a.log.5.gz',
 '/abc/a.log.4.gz',
 '/abc/a.log.3.gz',
 '/abc/a.log.2.gz',
 '/abc/a.log.1.gz']

该函数确保没有整数组件的文件名最后排序(首先,如果您按降序排序)。此外,所有“.log”文件都排在第一位。


推荐阅读