Python з будь-якої причини не має вбудованого способу природного сортування (мається на увазі 1, 2, 10 замість 1, 10, 2), тому вам доведеться писати це самостійно:
import re
def sorted_alphanumeric(data):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(data, key=alphanum_key)
Тепер ви можете використовувати цю функцію для сортування списку:
dirlist = sorted_alphanumeric(os.listdir(...))
ПРОБЛЕМИ:
Якщо ви використовуєте вищевказану функцію для сортування рядків (наприклад, імен папок) і хочете, щоб вони були сортовані так, як це робить Провідник Windows, вона не працюватиме належним чином у деяких крайових випадках.
Ця функція сортування поверне неправильні результати в Windows, якщо у вас є імена папок із певними "спеціальними" символами. Наприклад, ця функція буде сортувати 1, !1, !a, a, тоді як Windows Explorer буде сортувати !1, 1, !a, a.
Отже, якщо ви хочете сортувати точно так, як це робить Windows Explorer у Python, вам слід використовувати вбудовану функцію Windows StrCmpLogicalW через ctypes (це, звичайно, не буде працювати на Unix):
from ctypes import wintypes, windll
from functools import cmp_to_key
def winsort(data):
_StrCmpLogicalW = windll.Shlwapi.StrCmpLogicalW
_StrCmpLogicalW.argtypes = [wintypes.LPWSTR, wintypes.LPWSTR]
_StrCmpLogicalW.restype = wintypes.INT
cmp_fnc = lambda psz1, psz2: _StrCmpLogicalW(psz1, psz2)
return sorted(data, key=cmp_to_key(cmp_fnc))
Ця функція трохи повільніше, ніж sorted_alphanumeric().
Бонус: winsortтакож можна сортувати повні шляхи в Windows .
Крім того, особливо якщо ви використовуєте Unix, ви можете використовувати natsortбібліотеку ( pip install natsort) для сортування по повних шляхах правильним чином (маючи на увазі підпапки у правильному положенні).
Ви можете використовувати його так для сортування повних контурів:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
Не використовуйте його для звичайного сортування лише назв папок (або рядків загалом), оскільки це досить повільно, ніж sorted_alphanumeric()функціонування вище.
natsortedбібліотека дасть неправильні результати, якщо ви очікуєте сортування Windows Explorer, тому використовуйте winsort()для цього.