发现用os.listdir读取文件夹中的文件,返回的文件名不一定是顺序的。。。之前一直都没注意到这个问题,尴尬。然后就查找博客解决问题,可发现博客里都只讲了在文件名全是数字时的解决方案,可我的文件名带数字、字母和字符。。。没办法,自己动手,丰衣足食。
1 每个文件名里字母和字符都是一样的,只有数字参与排序。这种最简单了
如图中这个文件夹,文件名由数字和字母组合,只有数字参与排序。
import os
import re
path='D:/test/'
files= os.listdir(path)
查看一下返回结果
可以看到返回的结果并不是按顺序排列的
解决思路:因为只有数字参与排序,所以我们只需先将数字提取出来,对数字进行排序就可以了。提取字符串里的数字用到re模块的re.sub函数,详情见https://www.runoob.com/python3/python3-reg-expressions.html
c=[]
for f in files:
f=re.sub("\D", "", f)
c.append(f)
c_1=sorted(list(map(int, c)))
new_files=[('C'+str(i)+'.csv') for i in c_1]
代码简单就不多做介绍了,可以看到返回的结果已经是一个按顺序排列的列表了。
2 文件名里字母代表类别,参与排序
import os
import re
path='D:/test/'
files= os.listdir(path)
查看一下返回结果
解决思路:字母优先排序然后对数字排序。
r=[]
for f in files:
f_w=''.join(re.findall(r'[A-Za-z]', f))[:-3]
f_n=re.sub("\D", "", f)
f_n=int(f_n)
ff=(f_w,f_n)
r.append(ff)
分别提取字母、数字。提取所用模块还是re
re=sorted(r, key=lambda x: (x[0], x[1]))
然后使用sorted函数对其进行排序
new_files=[(re[i][0]+str(re[i][1])+'.csv') for i in range (len(re))]
最后得到new_files
代码本身并不难,就不详细介绍了
3 文件名中由两组数做排列
如图,字母代表类别,有两个数值
解决思路:与2类似,需要分别提取这两个数,然后进行排序
import os
import re
path='D:/test/'
files= os.listdir(path)
提取数值。如果用前面提到的re.sub()函数的话,以’C3_R9.tif’为例,返回的是39,而没有将两个数分开。所以这里我们用re.findall()函数,但发现后面数多了个小数点,将其舍弃
f='C3_R9.tif'
f1=re.sub("\D", "", f)
f2=re.findall(r"\d+\.?\d*",f)
print(f1)
print(f2)
out
39
['3', '9.']
f2=(f2[0],f2[1][:-1])
print(f2)
out
('3', '9')
完整代码如下
import os
import re
path='D:/test/'
files= os.listdir(path)
r=[]
for f in files:
f1=re.findall(r"\d+\.?\d*",f)
f1=(f1[0],f1[1][:-1])
f1=list(map(int, f1))
r.append(f1)
re=sorted(r, key=lambda x: (x[0], x[1]))
new_files=['C'+(str(re[i][0])+'_'+'R'+str(re[i][1])+'.tif') for i in range (len(re))]
查看结果
常用文件命名方式大抵就这三种了吧,反正我基本是这样的。。
水平有限,现时只能写出这样的解决方案。如有更好的方法还望赐教。