Python, por qualquer motivo, não vem com uma maneira embutida de ter classificação natural (ou seja, 1, 2, 10 em vez de 1, 10, 2), então você mesmo deve escrever:
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)
Agora você pode usar esta função para classificar uma lista:
dirlist = sorted_alphanumeric(os.listdir(...))
PROBLEMAS:
Se você usar a função acima para classificar strings (por exemplo, nomes de pastas) e quiser classificá-las como o Windows Explorer faz, isso não funcionará corretamente em alguns casos extremos.
Esta função de classificação retornará resultados incorretos no Windows, se você tiver nomes de pastas com certos caracteres 'especiais'. Por exemplo, esta função irá classificar 1, !1, !a, a
, enquanto o Windows Explorer irá classificar !1, 1, !a, a
.
Portanto, se você deseja classificar exatamente como o Windows Explorer faz no Python, você deve usar a função integrada do Windows StrCmpLogicalW via ctypes (isso é claro não funcionará no 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))
Esta função é ligeiramente mais lenta do que sorted_alphanumeric()
.
Bônus: winsort
também pode classificar caminhos completos no Windows .
Alternativamente, especialmente se você usar Unix, você pode usar a natsort
biblioteca ( pip install natsort
) para classificar por caminhos completos de maneira correta (significando subpastas na posição correta).
Você pode usá-lo assim para classificar caminhos completos:
from natsort import natsorted, ns
dirlist = natsorted(dirlist, alg=ns.PATH | ns.IGNORECASE)
Não o use para classificação normal apenas de nomes de pastas (ou strings em geral), pois é um pouco mais lento do que a sorted_alphanumeric()
função acima.
natsorted
biblioteca fornecerá resultados incorretos se você espera a classificação do Windows Explorer, então use winsort()
para isso.