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()
для цього.