Подтвердить что ты не робот

В каком порядке итерация os.walk повторяется?

Я обеспокоен порядком файлов и каталогов, предоставленных os.walk(). Если у меня есть эти каталоги, 1, 10, 11, 12, 2, 20, 21, 22, 3, 30, 31, 32, каков порядок вывода списка?

Это отсортировано по числовым значениям?

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

Или отсортированы по значениям ASCII, например, как указано в ls?

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

Кроме того, как я могу получить определенный вид?

4b9b3361

Ответ 1

os.walk использует os.listdir. Ниже приведена docstring для os.listdir:

listdir (путь) → list_of_strings

Возвращает список, содержащий имена записей в каталоге.

path: path of directory to list

Список находится в произвольном порядке. Он не включает специальные записи '.' и "..", даже если они присутствуют в каталоге.

(мой акцент).

Однако вы можете использовать sort для обеспечения желаемого порядка.

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

(Обратите внимание, что dirnames - это строки не ints, поэтому sorted(dirs) сортирует их как строки - что желательно за один раз.

Как отмечают Альф и Сиро Сантилли, если вы хотите, чтобы каталоги были переупорядочены в отсортированном порядке, измените dirs на месте:

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

Вы можете проверить это самостоятельно:

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)

печатает

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

Если вы хотите перечислить их в числовом порядке, используйте:

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

Для сортировки буквенно-цифровых строк используйте натуральный сорт.

Ответ 2

os.walk() дает на каждом шаге, что он будет делать на следующих шагах. Вы можете в каждом шаге влиять на порядок следующих шагов, сортируя списки так, как вы хотите. Цитирование руководства 2.7:

Когда значение "Понижение" равно "Истина", вызывающий может изменить список имен dirnames на месте (возможно, используя назначение del или slice), и walk() будет только возвращаться в подкаталоги, имена которых остаются в dirnames; это можно использовать для обрезки поиска, наложения определенного порядка посещения

Таким образом, сортировка dirNames будет влиять на порядок, в котором они будут посещаться:

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

После этого dirNames будут отсортированы на месте, а последующие значения walk будут соответственно.

Конечно, вы также можете отсортировать список fileNames, но это не повлияет на дальнейшие шаги (потому что файлы не будут иметь потомки walk).

И, конечно же, вы можете перебирать отсортированные версии этих списков как предложения unutbu, но это не повлияет на дальнейший прогресс самого walk.

Немодифицированный порядок значений undefined на os.walk, что означает, что это будет "любой" порядок. Вы не должны полагаться на то, что вы испытываете сегодня. Но на самом деле это, вероятно, будет то, что возвращает базовая файловая система. В некоторых файловых системах это будет упорядочено по алфавиту.

Ответ 3

Самый простой способ - сортировать возвращаемые значения os.walk(), например. с помощью:

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