Python如何按1至15的原始顺序读取文件夹内编号命名的mkv文件
问题原因
os.listdir返回的文件名默认按字符串字典序排序,数字作为字符串比较时,"10"的首字符'1'ASCII码小于'2',所以会出现10-15的文件排在1-9前面的情况。
正确实现方案
你原本使用sorted加lambda转整数的逻辑核心是对的,只需要补充过滤逻辑、规避路径硬编码问题即可,优化后的完整代码如下:
from pathlib import Path import os import subprocess import glob def split_vidoe(dir_main,dir_res): # 自动创建结果目录,避免路径不存在报错 Path(dir_res).mkdir(exist_ok=True, parents=True) # 先过滤所有mkv后缀文件,再按文件名数字排序 fnames_main = sorted( [p for p in Path(dir_main).iterdir() if p.suffix.lower() == '.mkv'], key=lambda path: int(path.stem) ) print(len(fnames_main)) # 用enumerate简化索引计算,从1开始计数 for idx, file_path in enumerate(fnames_main, start=1): # 用Path自带的拼接方法替代硬编码\\,兼容多平台 pname2 = Path(dir_res) / f"{idx}_" subprocess.call([ 'ffmpeg.exe','-i', str(file_path), '-c:v','libx264','-pix_fmt' ,'yuv420p', '-b:v', '8000K', '-bufsize', '8000K' , '-minrate', '8000K','-maxrate', '8000K', '-x264opts','keyint=60:min-keyint=60', '-preset', 'veryfast', '-profile:v', 'high', '-f', 'hls', '-hls_time', '2', '-hls_list_size','0', str(pname2) ]) return current_path=os.path.abspath(os.getcwd()) current_dir = Path.cwd() all_sub_dir_paths = glob(str(current_dir) + '/*/') all_sub_dir_names = [Path(sub_dir).name for sub_dir in all_sub_dir_paths] for i in range(len(all_sub_dir_names)): dir_main=current_path+'\\'+all_sub_dir_names[i] dir_res=current_path+'\\'+all_sub_dir_names[i]+'\\'+'gop_split'+'\\' split_vidoe(dir_main,dir_res)
如果不想用pathlib,也可以用os模块的写法实现排序:
os.chdir(dir_main) # 先过滤mkv文件 files = [x for x in os.listdir() if x.endswith(".mkv")] # 按文件名去掉后缀后的数字大小排序 fnames_main = sorted(files, key=lambda x: int(os.path.splitext(x)[0])) # 转成绝对路径 fnames_main = [os.path.abspath(x) for x in fnames_main]
注意事项
要保证所有mkv文件的文件名(不含后缀)都是纯数字,否则转int会报错。如果存在少量不符合命名规则的文件,可以修改排序key做兼容,比如:lambda path: int(path.stem) if path.stem.isdigit() else 9999,不符合规则的文件会自动排到最后。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

