web-dev-qa-db-ja.com

os.walkはどの順序で反復しますか?

os.walk()で指定されたファイルとディレクトリの順序が心配です。これらのディレクトリがある場合、110111222021223303132、出力リストの順序は何ですか?

数値でソートされていますか?

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

また、特定の並べ替えを取得するにはどうすればよいですか?

57
Vahid Mirjalili

_os.walk_は_os.listdir_を使用します。 _os.listdir_のdocstringは次のとおりです。

listdir(path)-> 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)
_

(ディレクトリ名はintではなく文字列なので、sorted(dirs)はそれらを文字列としてソートします。

AlfeとCiro Santilliが指摘しているように、ディレクトリをソートされた順序で再帰にしたい場合は、dirsin-placeを変更します

_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):
_

英数字の文字列を並べ替えるには、 自然な並べ替え を使用します。

84
unutbu

os.walk()は、各ステップで次のステップで行うことを提供します。リストを希望する方法で並べ替えることにより、各ステップで次のステップの順序に影響を与えることができます。引用 2.7マニュアル

TopdownがTrueの場合、呼び出し元はdirnamesリストをインプレースで変更でき(おそらくdelまたはスライス割り当てを使用)、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自体のさらなる進歩に影響を与えません。

値の変更されていない順序はos.walkで定義されていないため、「任意の」順序になります。今日の経験に頼るべきではありません。しかし、実際には、基礎となるファイルシステムが返すものになるでしょう。一部のファイルシステムでは、これはアルファベット順になります。

34
Alfe

最も簡単な方法は、os.walk()の戻り値をソートすることです。使用して:

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