你如何按数字排序文件?

Zac*_*ung 25 python sorting

首先,我发布这个是因为当我在寻找下面问题的解决方案时,我在stackoverflow上找不到一个.所以,我希望在这里添加一点知识库.

我需要处理目录中的一些文件,并且需要以数字方式对文件进行排序.我lambdawiki.python.org上找到了一些关于排序的例子 - 特别是使用模式 - 我把它放在一起:

#!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
Run Code Online (Sandbox Code Playgroud)

我仍然是Python的新手,并且想问社区是否可以对此进行任何改进:缩短代码(删除lambda),性能,样式/可读性?

谢谢Zachary

Dan*_*olo 45

这称为"自然排序"或"人类排序"(与字典排序相反,这是默认排序). Ned B写了一个快速版本.

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)
Run Code Online (Sandbox Code Playgroud)

它与你正在做的类似,但也许更广泛.

  • 谢谢你,丹尼尔!这正是我所寻找的。我按照你提供的链接进入了兔子洞……哎呀!!!我了解了一些有关 try/ except 的性能,以及(当然)预编译正则表达式的知识。:) (2认同)
  • @Zachary Young:我怀疑处理负数对你来说并不重要,但发表评论只是让其他人注意到这一事实(毕竟,你的问题只是说“数字”)。这很容易修复,只需使用 `re.split('(-*[0-9]+)', s)` 代替......更一般地说,它可以用来处理[有符号]实数,例如`-3.14`,通过使用 `re.split('(-*\d+\.\d*)' , s)`。最后,如果您不想定义像“sort_nicely()”这样的单独函数,您可以随时使用“tiffFiles.sort(key=alphanum_key)”,就像您在问题代码中所做的那样。 (2认同)

dkm*_*tt0 10

只需使用:

tiffFiles.sort(key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])
Run Code Online (Sandbox Code Playgroud)

比使用try/except更快.


yoo*_*ghm 6

@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]))
Run Code Online (Sandbox Code Playgroud)


Don*_*ell 5

如果您key=在sort方法中使用cmp,则不应使用从最新版本的Python中删除的方法. key应该等同于一个函数,该函数将记录作为输入并返回将按照您希望列表排序的顺序进行比较的任何对象.它不需要是一个lambda函数,可能作为一个独立的函数更清晰.正则表达式的评估速度也很慢.

您可以尝试类似以下内容来隔离并返回文件名的整数部分:

def getint(name):
    basename = name.partition('.')
    alpha, num = basename.split('_')
    return int(num)
tiffiles.sort(key=getint)
Run Code Online (Sandbox Code Playgroud)