Domanda os.walk itera in quale ordine? [duplicare]


Questa domanda ha già una risposta qui:

Sono preoccupato per l'ordine di file e directory dati da os.walk(). Se ho queste directory, 1, 10, 11, 12, 2, 20, 21, 22, 3, 30, 31, 32, qual è l'ordine dell'elenco di output?

È ordinato in base a valori numerici?

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

O ordinato per valori ASCII, come quello che viene dato da ls?

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

E come posso ottenere un ordine specifico?


44
2017-08-16 21:27


origine


risposte:


os.walk usi os.listdir. Ecco la docstring per os.listdir:

listdir (percorso) -> list_of_strings

Restituisce una lista contenente i nomi delle voci nella directory.

path: path of directory to list

L'elenco è in ordine arbitrario. Non include lo speciale   inserimenti '.' e '..' anche se sono presenti nella directory.

(la mia enfasi).

Potresti, tuttavia, usare sort per garantire l'ordine desiderato.

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

(Nota che i nomi non sono stringhe, quindi sorted(dirs) li ordina come stringhe - il che è desiderabile per una volta.

Come sottolineano Alfe e Ciro Santilli, se vuoi che le directory siano ricorsivo in ordine ordinato, quindi modificare dirs  a posto:

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

Puoi testarlo da solo:

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)

stampe

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

Se si desidera elencarli in ordine numerico, utilizzare:

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

Per ordinare le stringhe alfanumeriche, utilizzare specie naturale.


61
2017-08-16 21:29



os.walk() produce in ogni fase ciò che farà nei prossimi passi. È possibile in ogni passaggio influenzare l'ordine dei passaggi successivi ordinando gli elenchi nel modo desiderato. citando il manuale 2.7:

Quando TopDown è True, il chiamante può modificare l'elenco dei nomi in loco (magari usando l'assegnazione del o slice), e walk () ricercherà solo nelle sottodirectory i cui nomi rimangono in dirnames; questo può essere usato per potare la ricerca, imporre un ordine specifico di visita

Quindi ordinando il dirNames influenzerà l'ordine in cui saranno visitati:

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

Dopo questo, il dirNames sono ordinati sul posto e i prossimi valori di rendimento di walk sarà di conseguenza.

Naturalmente puoi anche ordinare l'elenco di fileNames ma ciò non influenzerà ulteriori passaggi (perché i file non hanno discendenti walk Visiterò).

E naturalmente puoi scorrere le versioni ordinate di queste liste come propone la risposta di unutbu, ma ciò non influenzerà l'ulteriore progresso della walk si.

L'ordine non modificato dei valori non è definito da os.walk, il che significa che sarà "qualsiasi" ordine. Non dovresti fare affidamento su ciò che sperimenti oggi. Ma in effetti sarà probabilmente ciò che restituisce il file system sottostante. In alcuni file system questo sarà ordinato alfabeticamente.


28
2017-08-16 21:47



Il modo più semplice è quello di ordinare i valori di ritorno di os.walk(), per esempio. utilizzando:

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

17
2017-09-16 12:15