Python:只按其中一个"部分"排序字符串。

时间:2016-11-02 22:06:31

标签: python sorting

通过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

有没有办法按照文件夹中显示的顺序提取文件?或者也许我可以使用任何排序功能将它们按正确顺序放回去?感谢

3 个答案:

答案 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",因为尝试将strint进行比较是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']