通过os.listdir()
我创建了一个从文件夹中获取的数百个文件的列表。所有文件名都具有以下模式:
obj1__5
obj1__10
obj1__15
...
...
obj1__250
...
obj2__5
obj2__10
...
obj2__250
... and so on up to obj99
文件夹中的文件按照此方案排序,但是在使用os.listdir()
时,我得到了以这种方式订购的列表:
obj1__0.png
obj1__10.png
obj1__100.png
obj1__105.png
...
obj1__145.png
obj1__15.png
obj1__150.png
obj1__155.png
...
obj1__190.png
obj1__195.png
obj1__20.png
obj1__200.png
obj1__205.png
... and so on
有没有办法按照文件夹中显示的顺序提取文件?或者也许我可以使用任何排序功能将它们按正确顺序放回去?感谢
答案 0 :(得分:3)
通用自然分类功能是这样的:
import re
def naturalsort(name, digits=re.compile("([0-9]+)")):
return [int(x) if x.isdigit() else x for x in digits.split(name)]
您将返回一个列表,其中包含数字运行的整数值和其余的字符串版本。您可以在排序时将其用作key
:
sorted(os.listdir(), key=naturalsort)
当您尝试比较时,您可能会认为这会导致Python 3出现问题。 "的abc.txt"使用" 123.txt",因为尝试将str
与int
进行比较是Py3中的错误。它仍然有效:因为我们在数字运行时分裂,对于以数字运行开头的字符串,键的第一个元素是''
。它将编号的项目放在任何字母之前,因为它们应该是。另一种说法是键的第一个元素总是一个字符串(可能是空的),第二个元素总是一个整数,依此类推,直到字符串的结尾。因此,Python永远不会尝试比较不同的类型。
答案 1 :(得分:1)
这应该适合你。
import os
import re
def splitter(name):
reg = re.search("(\d+)__(\d+)", name)
return (int(reg.group(1)), int(reg.group(2)))
files = map(lambda x: (x, splitter(x)[0], splitter(x)[1]), os.listdir())
temp = sorted(files, key = lambda x: (x[1], x[2]))
sortedFiles = map(lambda x: x[0], temp)
key
函数的sorted
参数实质上是一个多参数排序,按第一个参数排序,然后在尊重第一级排序的同时对第二个参数进行排序。
答案 2 :(得分:-1)
您可以尝试:
>>> l = ['obj1__0.png', 'obj1__10.png', 'obj3__15.png', 'obj1__15.png', 'obj2__15.png', 'obj1__100.png']
>>>
>>> sorted(l, key=lambda x: (int(x.split('__')[0][3:]),int(x.split('__')[1].strip('.png'))))
['obj1__0.png', 'obj1__10.png', 'obj1__15.png', 'obj1__100.png', 'obj2__15.png', 'obj3__15.png']