Подтвердить что ты не робот

Как вы сортируете файлы численно?

Во-первых, я публикую это, потому что, когда я искал решение проблемы ниже, я не смог найти его в stackoverflow. Итак, я надеюсь добавить немного к базе знаний здесь.

Мне нужно обработать некоторые файлы в каталоге и нуждаться в сортировке файлов в численном порядке. Я нашел несколько примеров сортировки - особенно с использованием шаблона lambda - в wiki.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

Я все еще довольно новичок в Python и хотел бы спросить сообщество, есть ли какие-либо улучшения, которые могут быть сделаны для этого: сокращение кода вверх (удаление lambda), производительность, стиль/удобочитаемость?

Спасибо, Zachary

4b9b3361

Ответ 1

Это называется "естественная сортировка" или "сортировка человека" (в отличие от лексикографической сортировки, которая является значением по умолчанию). 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)

Он похож на то, что вы делаете, но, возможно, немного более обобщен.

Ответ 2

Если вы используете key= в своем методе сортировки, вы не должны использовать cmp, который был удален из последних версий Python. key следует приравнять к функции, которая берет запись как входную и возвращает любой объект, который будет сравниваться в том порядке, в котором вы хотите отсортировать список. Он не должен быть лямбда-функцией и может быть более ясным как автономная функция. Также регулярные выражения могут быть медленными для оценки.

Вы можете попробовать что-то вроде следующего, чтобы изолировать и вернуть целочисленную часть имени файла:

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

Ответ 3

Просто используйте:

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.

Ответ 4

Результаты разбивки на Tuple

def getint(name):
    (basename, part, ext) = name.partition('.')
    (alpha, num) = basename.split('_')
    return int(num)