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 будет выполнять сортировку !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()
для этого.