Python per qualsiasi motivo non viene fornito con un modo integrato per avere l'ordinamento naturale (che significa 1, 2, 10 invece di 1, 10, 2), quindi devi scriverlo da solo:
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)
È ora possibile utilizzare questa funzione per ordinare un elenco:
dirlist = sorted_alphanumeric(os.listdir(...))
PROBLEMI:
Nel caso in cui utilizzi la funzione sopra per ordinare le stringhe (ad esempio i nomi delle cartelle) e desideri che vengano ordinate come fa Windows Explorer, non funzionerà correttamente in alcuni casi limite.
Questa funzione di ordinamento restituirà risultati errati su Windows, se sono presenti nomi di cartelle con determinati caratteri "speciali". Ad esempio, questa funzione ordinerà 1, !1, !a, a
, mentre Windows Explorer ordinerà !1, 1, !a, a
.
Quindi, se vuoi ordinare esattamente come fa Windows Explorer in Python, devi usare la funzione incorporata di Windows StrCmpLogicalW tramite ctypes (questo ovviamente non funzionerà su 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))
Questa funzione è leggermente più lenta di sorted_alphanumeric()
.
Bonus: winsort
può anche ordinare percorsi completi su Windows .
In alternativa, specialmente se usi Unix, puoi usare natsort
library ( pip install natsort
) per ordinare i percorsi completi in modo corretto (cioè sottocartelle nella posizione corretta).
Puoi usarlo in questo modo per ordinare i percorsi completi:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
Non usarlo per il normale ordinamento dei soli nomi di cartelle (o stringhe in generale), poiché è un po 'più lento di quanto sorted_alphanumeric()
funzioni sopra.
natsorted
library ti darà risultati errati se ti aspetti l'ordinamento di Windows Explorer, quindi usa winsort()
per quello.