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: winsort
można również sortować pełne ścieżki w systemie Windows .
Alternatywnie, zwłaszcza jeśli używasz Uniksa, możesz użyć natsort
biblioteki ( 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.
natsorted
biblioteka da nieprawidłowe wyniki, jeśli spodziewasz się sortowania w Eksploratorze Windows, więc użyj winsort()
do tego.