Z jakiegoś powodu Python nie ma wbudowanego sposobu na naturalne sortowanie (czyli 1, 2, 10 zamiast 1, 10, 2), więc musisz napisać to sam:
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)
Możesz teraz użyć tej funkcji do sortowania listy:
dirlist = sorted_alphanumeric(os.listdir(...))
PROBLEMY:
Jeśli użyjesz powyższej funkcji do sortowania ciągów (na przykład nazw folderów) i chcesz, aby były posortowane tak, jak robi to Eksplorator Windows, nie będzie ona działać poprawnie w niektórych skrajnych przypadkach.
Ta funkcja sortowania zwróci nieprawidłowe wyniki w systemie Windows, jeśli masz nazwy folderów z określonymi znakami „specjalnymi”. Na przykład ta funkcja posortuje 1, !1, !a, a, podczas gdy Eksplorator Windows posortuje !1, 1, !a, a.
Więc jeśli chcesz sortować dokładnie tak, jak robi to Eksplorator Windows w Pythonie , musisz użyć wbudowanej funkcji Windows StrCmpLogicalW poprzez ctypes (to oczywiście nie zadziała na Uniksie):
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))
Ta funkcja jest nieco wolniejsza niż sorted_alphanumeric().
Bonus: winsortmożna również sortować pełne ścieżki w systemie Windows .
Alternatywnie, zwłaszcza jeśli używasz Uniksa, możesz użyć natsortbiblioteki ( pip install natsort) do sortowania według pełnych ścieżek w prawidłowy sposób (co oznacza podfoldery we właściwej pozycji).
Możesz go użyć w ten sposób do sortowania pełnych ścieżek:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
Nie używaj go do normalnego sortowania tylko nazw folderów (lub ogólnie ciągów znaków), ponieważ jest to nieco wolniejsze niż sorted_alphanumeric()funkcja powyżej.
natsortedbiblioteka da nieprawidłowe wyniki, jeśli spodziewasz się sortowania w Eksploratorze Windows, więc użyj winsort()do tego.