有没有办法(如 php 的 natsort)对由文件名组成的列表进行排序,这些文件名仅在一个数字上不同,并且按 glob 未排序返回,例如:
test1.dat
test7.dat
.
.
test10.dat
test3.dat
当我进行天真的排序时,结果是
test1.dat
test10.dat
test2.dat
.
.
.
因为 1 出现在 2 之前 :) 我可以用 for 循环和范围(或带范围的生成器)构造一些东西,但这感觉有点不合常理......
sorted(glob.glob('*.dat'), key=lambda x: int(x.split('.')[0][4:]))
这将获取文件名,去除扩展名并获取第四个位置之后字符的整数值。适用于“testXXX.dat”,其中 XXX 是任意长度的整数。
使用 re 的解决方案(未经测试):
prefix_number=re.compile(r'(.*)(\d+)\.dat$')
def sortkey(ss):
match=prefix_number.match(ss)
if(match):
return (match.group(0),int(match.group(1))
else:
return (ss,)
sorted(glob.iglob('*.dat'), key=sortkey )
此解决方案通过按前缀(例如“test”)和整数(例如 1)拆分文件名来工作。然后它首先按前缀排序,然后按整数排序。当然,缺点是你需要re
一个稍微复杂一点的解决方案。
eumiro的回答很好。我只是想添加一个更灵活的方法:
def natural_sort(data):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(data, key=alphanum_key)