¿En qué orden itera it.a os.walk?

Me preocupa el orden de los archivos y directorios dado por os.walk() . Si tengo estos directorios, 1 , 10 , 11 , 12 , 2 , 20 , 21 , 22 , 3 , 30 , 31 , 32 , ¿cuál es el orden de la lista de salida?

¿Está ordenado por valores numéricos?

 1 2 3 10 20 30 11 21 31 12 22 32 

¿O ordenado por valores ASCII, como lo que da ls ?

 1 10 11 12 2 20 21 22 3 30 31 32 

Además, ¿cómo puedo obtener un tipo específico?

os.walk utiliza os.listdir . Aquí está la cadena de os.listdir para os.listdir :

listdir (ruta) -> list_of_strings

Devuelve una lista que contiene los nombres de las entradas en el directorio.

 path: path of directory to list 

La lista está en orden arbitrario . No incluye las entradas especiales ‘.’ y ‘..’ incluso si están presentes en el directorio.

(mi énfasis).

Sin embargo, puede utilizar la sort para garantizar el orden que desee.

 for root, dirs, files in os.walk(path): for dirname in sorted(dirs): print(dirname) 

(Tenga en cuenta que los dirnames son cadenas no ints, así que sorted(dirs) clasifican como cadenas, lo que es deseable por una vez.

Como lo señalan Alfe y Ciro Santilli, si desea que los directorios se repitan en orden ordenado, modifique los directorios in situ :

 for root, dirs, files in os.walk(path): dirs.sort() for dirname in dirs: print(os.path.join(root, dirname)) 

Puede probar esto usted mismo:

 import os os.chdir('/tmp/tmp') for dirname in '1 10 11 12 2 20 21 22 3 30 31 32'.split(): try: os.makedirs(dirname) except OSError: pass for root, dirs, files in os.walk('.'): for dirname in sorted(dirs): print(dirname) 

huellas dactilares

 1 10 11 12 2 20 21 22 3 30 31 32 

Si desea listarlos en orden numérico use:

 for dirname in sorted(dirs, key=int): 

Para ordenar las cadenas alfanuméricas, utilice la ordenación natural .

os.walk() produce en cada paso lo que hará en los siguientes pasos. En cada paso puede influir en el orden de los siguientes pasos ordenando las listas de la forma que desee. Citando el manual 2.7 :

Cuando topdown es Verdadero, la persona que llama puede modificar la lista de nombres de usuarios en el lugar (tal vez utilizando la asignación del o slice), y walk () solo retrocederá en los subdirectorios cuyos nombres permanezcan en los nombres de los nombres; Esto se puede usar para podar la búsqueda, imponer un orden específico de visitas.

Por lo tanto, la clasificación de los dirNames influirá en el orden en que serán visitados:

 for rootName, dirNames, fileNames in os.walk(path): dirNames.sort() # you may want to use the args cmp, key and reverse here 

Después de esto, los dirNames se ordenan en el lugar y los siguientes valores de walk serán en consecuencia.

Por supuesto, también puede ordenar la lista de nombres de fileNames pero eso no influirá en ningún otro paso (porque los archivos que no tienen descendientes walk que visitará).

Y, por supuesto, puede recorrer las versiones ordenadas de estas listas como propone la respuesta de unutbu, pero eso no influirá en el progreso de la walk .

El orden no modificado de los valores no está definido por os.walk , lo que significa que será “cualquier” orden. No debes confiar en lo que experimentas hoy. Pero, de hecho, probablemente será lo que devuelve el sistema de archivos subyacente. En algunos sistemas de archivos esto será ordenado alfabéticamente.

La forma más sencilla es ordenar los valores de retorno de os.walk() , por ejemplo, usando:

 for rootName, dirNames, fileNames in sorted(os.walk(path)): #root, dirs and files are iterated in order...