Как вы сортируете файлы численно? - PullRequest
24 голосов
/ 07 января 2011

Прежде всего, я публикую это, потому что, когда я искал решение для проблемы ниже, я не мог найти его в 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

Ответы [ 5 ]

44 голосов
/ 07 января 2011

Это называется «естественной сортировкой» или «сортировкой человека» (в отличие от лексикографической сортировки, которая используется по умолчанию). Нед Б. написал быструю версию.

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)

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

9 голосов
/ 24 марта 2016

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

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

быстрее, чем использовать try / исключением.

5 голосов
/ 07 января 2011

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

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

def getint(name):
    basename = name.partition('.')
    alpha, num = basename.split('_')
    return int(num)
tiffiles.sort(key=getint)
0 голосов
/ 18 октября 2018

Это модифицированная версия ответа @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) Используйте sorted вместо list.sort, для https://docs.python.org/2/howto/sorting.html

0 голосов
/ 15 июля 2015

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

def getint(name):
    (basename, part, ext) = name.partition('.')
    (alpha, num) = basename.split('_')
    return int(num)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...