Python pour une raison quelconque ne vient pas avec un moyen intégré d'avoir un tri naturel (ce qui signifie 1, 2, 10 au lieu de 1, 10, 2), vous devez donc l'écrire vous-même:
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)
Vous pouvez maintenant utiliser cette fonction pour trier une liste:
dirlist = sorted_alphanumeric(os.listdir(...))
PROBLÈMES:
Si vous utilisez la fonction ci-dessus pour trier les chaînes (par exemple les noms de dossier) et que vous voulez les trier comme le fait l'Explorateur Windows, cela ne fonctionnera pas correctement dans certains cas extrêmes.
Cette fonction de tri renverra des résultats incorrects sous Windows, si vous avez des noms de dossier contenant certains caractères «spéciaux». Par exemple, cette fonction triera1, !1, !a, a
, alors que l'Explorateur Windows triera !1, 1, !a, a
.
Donc, si vous voulez trier exactement comme l'explorateur Windows le fait en Python, vous devez utiliser la fonction intégrée de Windows StrCmpLogicalW via ctypes (cela ne fonctionnera bien sûr pas sous 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))
Cette fonction est légèrement plus lente que sorted_alphanumeric()
.
Bonus: winsort
peut également trier les chemins complets sous Windows .
Alternativement, surtout si vous utilisez Unix, vous pouvez utiliser la natsort
bibliothèque ( pip install natsort
) pour trier par chemins complets d'une manière correcte (c'est-à-dire les sous-dossiers à la bonne position).
Vous pouvez l'utiliser comme ceci pour trier les chemins complets:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
Ne l'utilisez pas pour le tri normal des noms de dossiers (ou des chaînes en général), car c'est un peu plus lent que la sorted_alphanumeric()
fonction ci-dessus.
natsorted
La bibliothèque vous donnera des résultats incorrects si vous vous attendez à un tri dans l'Explorateur Windows, alors utilisez-le winsort()
pour cela.