首先,我发布这个是因为当我在寻找下面问题的解决方案时,我在stackoverflow上找不到一个。所以,我希望在这里为知识库添加一点点。
我需要处理目录中的一些文件,并且需要以数字方式对文件进行排序。我在wiki.python.org找到了一些关于排序的例子 - 特别是使用lambda
模式,我把它放在一起:
#!env/python
import re
tiffFiles = """ayurveda_1.tif
ayurveda_11.tif
ayurveda_13.tif
ayurveda_2.tif
ayurveda_20.tif
ayurveda_22.tif""".split('\n')
numPattern = re.compile('_(\d{1,2})\.', re.IGNORECASE)
tiffFiles.sort(cmp, key=lambda tFile:
int(numPattern.search(tFile).group(1)))
print tiffFiles
我仍然不熟悉Python,并且想询问社区是否可以对此进行任何改进:缩短代码(删除lambda
),性能,样式/可读性?< / p>
谢谢你, 扎卡里
答案 0 :(得分:43)
这称为“自然排序”或“人类排序”(与字典排序相反,这是默认排序)。 Ned B wrote up a quick version of one.
import re
def tryint(s):
try:
return int(s)
except:
return s
def alphanum_key(s):
""" Turn a string into a list of string and number chunks.
"z23a" -> ["z", 23, "a"]
"""
return [ tryint(c) for c in re.split('([0-9]+)', s) ]
def sort_nicely(l):
""" Sort the given list in the way that humans expect.
"""
l.sort(key=alphanum_key)
它与你正在做的类似,但也许更广泛。
答案 1 :(得分:9)
只需使用:
tiffFiles.sort(key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])
比使用try / except更快。
答案 2 :(得分:5)
如果您在排序方法中使用key=
,则不应使用已从最新版本的Python中删除的cmp
。 key
应该等同于一个函数,该函数将记录作为输入并返回将按照您希望列表排序的顺序进行比较的任何对象。它不需要是一个lambda函数,可能作为一个独立的函数更清晰。正则表达式的评估速度也很慢。
您可以尝试使用以下内容来隔离并返回文件名的整数部分:
def getint(name):
basename = name.partition('.')
alpha, num = basename.split('_')
return int(num)
tiffiles.sort(key=getint)
答案 3 :(得分:0)
分区导致元组
def getint(name):
(basename, part, ext) = name.partition('.')
(alpha, num) = basename.split('_')
return int(num)
答案 4 :(得分:0)
这是@Don O'Donnell答案的修改版本,因为我无法按原样工作,但我认为这是最好的答案,因为它已经得到了很好的解释。
def getint(name):
_, num = name.split('_')
num, _ = num.split('.')
return int(num)
print(sorted(tiffFiles, key=getint))
更改:
1)alpha
字符串未存储,因为不需要它(因此_, num
)
2)使用num.split('.')
将数字与.tiff分开
3)根据https://docs.python.org/2/howto/sorting.html,用sorted
代替list.sort
答案 5 :(得分:0)
@April在How is Pythons glob.glob ordered?中提供了一个很好的解决方案,您可以尝试
#First, get the files:
import glob
import re
files = glob.glob1(img_folder,'*'+output_image_format)
# Sort files according to the digits included in the filename
files = sorted(files, key=lambda x:float(re.findall("(\d+)",x)[0]))