A menudo uso Python para procesar directorios de datos. Recientemente, he notado que el orden predeterminado de las listas ha cambiado a algo casi sin sentido. Por ejemplo, si estoy en un directorio actual que contiene los siguientes subdirectorios: run01, run02, ... run19, run20, y luego genero una lista con el siguiente comando:
dir = os.listdir(os.getcwd())
entonces normalmente obtengo una lista en este orden:
dir = ['run01', 'run18', 'run14', 'run13', 'run12', 'run11', 'run08', ... ]
y así. El orden solía ser alfanumérico. Pero este nuevo orden ha permanecido conmigo por un tiempo.
¿Qué está determinando el orden (mostrado) de estas listas?
python
list
directory-listing
listdir
Marshall.ward
fuente
fuente
listdir
salida ordenada . No estoy seguro de por qué se fusionaron las preguntas.Respuestas:
Creo que el orden tiene que ver con la forma en que se indexan los archivos en su sistema de archivos. Si realmente desea que se adhiera a algún orden, siempre puede ordenar la lista después de obtener los archivos.
fuente
Puede utilizar la
sorted
función incorporada para ordenar las cadenas como desee. Basado en lo que describe,Alternativamente, puede utilizar el
.sort
método de una lista:Creo que debería hacer el truco.
Tenga en cuenta que el orden en el que se
os.listdir
obtienen los nombres de archivo probablemente dependa por completo de su sistema de archivos.fuente
sorted(listdir)
funcionó para mí.listdir.sort()
me dio: TypeError: el objeto 'NoneType' no es iterablereverse=True
para que sea de orden descendente.sorted
que está escrito primero lo hace en una sola línea, ¿de acuerdo?Según la documentación :
No se puede confiar en el orden y es un artefacto del sistema de archivos.
Para ordenar el resultado, use
sorted(os.listdir(path))
.fuente
Python, por la razón que sea, no viene con una forma incorporada de tener una clasificación natural (es decir, 1, 2, 10 en lugar de 1, 10, 2), por lo que debe escribirlo usted mismo:
Ahora puede usar esta función para ordenar una lista:
PROBLEMAS: En caso de que utilice la función anterior para ordenar cadenas (por ejemplo, nombres de carpetas) y desee ordenarlas como lo hace el Explorador de Windows, no funcionará correctamente en algunos casos extremos.
Esta función de clasificación devolverá resultados incorrectos en Windows, si tiene nombres de carpeta con ciertos caracteres 'especiales' en ellos. Por ejemplo, esta función ordenará
1, !1, !a, a
, mientras que el Explorador de Windows ordenará!1, 1, !a, a
.Entonces, si desea ordenar exactamente como lo hace el Explorador de Windows en Python , debe usar la función incorporada de Windows StrCmpLogicalW a través de ctypes (esto, por supuesto, no funcionará en Unix):
Esta función es un poco más lenta que
sorted_alphanumeric()
.Bonificación:
winsort
también puede ordenar rutas completas en Windows .Alternativamente, especialmente si usa Unix, puede usar la
natsort
biblioteca (pip install natsort
) para ordenar por rutas completas de manera correcta (es decir, subcarpetas en la posición correcta).Puede usarlo así para ordenar rutas completas:
No lo use para la clasificación normal de solo nombres de carpetas (o cadenas en general), ya que es un poco más lento que la
sorted_alphanumeric()
función anterior.natsorted
la biblioteca le dará resultados incorrectos si espera la clasificación del Explorador de Windows, así que úselowinsort()
para eso.fuente
print( sorted_aphanumeric(["1", "10", "2", "foo_10", "foo_8"]) )
->['1', '2', '10', 'foo_8', 'foo_10']
. Exactamente como se esperaba.natsorted
para implementar la funcionalidad de coincidencia del Explorador de Windows. ¿Quizás deberías aportar una solución? github.com/SethMMorton/natsort/issues/41Creo que, de forma predeterminada, el orden se determina con el valor ASCII. La solución a este problema es esta
fuente
Probablemente sea solo el orden en que
readdir()
regresa C. Intente ejecutar este programa en C:La línea de construcción debería ser algo así como
gcc -o foo foo.c
.PD: Acabo de ejecutar esto y su código Python, y ambos me dieron una salida ordenada, por lo que no puedo reproducir lo que está viendo.
fuente
Como en el caso de mi requisito, tengo el caso como
row_163.pkl
aquí,os.path.splitext('row_163.pkl')
lo dividiremos en,('row_163', '.pkl')
por lo que también es necesario dividirlo en función de '_'.pero en caso de que lo requiera, puede hacer algo como
dónde
y también para la recuperación de directorios puede hacer
sorted(os.listdir(path))
y para el caso de me gusta
'run01.txt'
o'run01.csv'
puedes hacer asífuente
Encontré que "sort" no siempre hace lo que esperaba. por ejemplo, tengo un directorio como el siguiente, y el "sort" me da un resultado muy extraño:
Parece que compara el primer carácter primero, si ese es el más grande, sería el último.
fuente
('5' > '403') is True
.De la documentación :
Esto significa que el orden probablemente depende del sistema de archivos / sistema operativo, no tiene un orden particularmente significativo y, por lo tanto, no se garantiza que sea algo en particular. Como se mencionaron muchas respuestas: si lo prefiere, la lista recuperada se puede ordenar.
Salud :)
fuente
La respuesta de Elliot lo resuelve a la perfección pero como es un comentario pasa desapercibido así que con el objetivo de ayudar a alguien lo estoy reiterando como solución.
Utilice la biblioteca natsort:
Instale la biblioteca con el siguiente comando para Ubuntu y otras versiones de Debian
Python 2
Python 3
Los detalles sobre cómo usar esta biblioteca se encuentran aquí
fuente
sorted()
! Graciasfuente
La combinación propuesta de os.listdir y comandos ordenados genera el mismo resultado que el comando ls -l en Linux. El siguiente ejemplo verifica esta suposición:
Entonces, para alguien que quiera reproducir el resultado del conocido comando ls -l en su código Python, sorted (os.listdir (DIR)) funciona bastante bien.
fuente