Как использовать natsort в python для сортировки имен папок? - PullRequest
1 голос
/ 09 марта 2020

У меня есть три папки, имена которых ["-folder2-", "-folder1-", "=Folder-"].

Когда я использую 'sorted' или в Window, он возвращает ["-folder-", "-folder1-", "-folder2-"]. Но используя natsort, он возвращает ["-folder1-", "-folder2-", "-folder-"].

Я хочу получить тот же результат, используя natsort Как я могу это сделать?

a = ["-folder1-", "-folder2-", "-folder-"]
import natsort
sorting = natsort.natsorted(a, alg = natsort.ns.PATH | natsort.ns.LOCALE | natsort.ns.IGNORECASE)
print(sorted(a)) #---> ["-folder-", "-folder1-", "-folder2-"]
print(sorting) #---> ["-folder1-", "-folder2-", "-folder-"]

1 Ответ

1 голос
/ 10 марта 2020

Прежде чем я отвечу на ваш вопрос, сначала я хочу объяснить, что происходит. natsort ищет числа на вашем входе и отделяет их от нечислительных c компонентов. Самый простой способ убедиться в этом - посмотреть на вывод ключа естественной сортировки. (Я пропустил опции PATH и LOCALE, потому что они полностью искажают вывод).

>>> import natsort
>>> ns_key = natsort.natsort_keygen(alg=natsort.IGNORECASE)
>>> a = ["-folder1-", "-folder2-", "-folder-"]
>>> [ns_key(x) for x in a]
[('-folder', 1, '-'), ('-folder', 2, '-'), ('-folder-',)]

Когда '-folder' сравнивается с '-folder-', первое считается первым согласно Python сортирует эвристику, поэтому ваши папки с номерами размещаются первыми.

Чтобы ответить на ваш вопрос, нам нужно обмануть natsort, думая, что '-', за которым не следует чисел, следует рассматривать как случай с номерами. Один из способов сделать это - с помощью регулярных выражений.

>>> import re
>>> r = re.compile(r"(?<!\d)-")
>>> # What does the regex do?
>>> [r.sub("0\g<0>", x) for x in a]
['0-folder1-', '0-folder2-', '0-folder0-']
>>> # What does natsort generate?
>>> ns_key = natsort.natsort_keygen(key=lambda x: r.sub("0\g<0>", x), alg=natsort.IGNORECASE)
>>> [ns_key(x) for x in a]
[('', 0, '-folder', 1, '-'), ('', 0, '-folder', 2, '-'), ('', 0, '-folder', 0, '-')]
>>> # Does it actually work?
>>> natsort.natsorted(a, key=lambda x: r.sub("0\g<0>", x), alg=natsort.ns.PATH | natsort.ns.LOCALE | natsort.ns.IGNORECASE)
['-folder-', '-folder1-', '-folder2-']

Альтернативным методом будет «разделить» ваш ввод на '-', что будет иметь аналогичный эффект. Это одна из вещей, которые PATH под капотом, но для разделителей файлов.

>>> # What does natsort generate?
>>> ns_key = natsort.natsort_keygen(key = lambda x: x.split('-'), alg=natsort.IGNORECASE)
>>> [ns_key(x) for x in a]
[((), ('folder', 1), ()), ((), ('folder', 2), ()), ((), ('folder',), ())]
>>> # Does it actually work?
>>> natsort.natsorted(a, key=lambda x: x.split('-'), alg=natsort.ns.PATH | natsort.ns.LOCALE | natsort.ns.IGNORECASE)
['-folder-', '-folder1-', '-folder2-']

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

...