os.walk迭代迭代的顺序是什么?

Vah*_*ili 60 python sorting 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
Run Code Online (Sandbox Code Playgroud)

或者按ASCII值排序,就像给出的那样ls

1 10 11 12 2 20 21 22 3 30 31 32
Run Code Online (Sandbox Code Playgroud)

另外,我该如何获得特定的排序?

unu*_*tbu 88

os.walk用途os.listdir.这是docstring os.listdir:

listdir(path) - > list_of_strings

返回包含目录中条目名称的列表.

path: path of directory to list
Run Code Online (Sandbox Code Playgroud)

该列表按任意顺序排列.它不包括特殊条目'.' 和'..'即使它们存在于目录中.

(我的重点).

但是,您可以使用它sort来确保您想要的订单.

for root, dirs, files in os.walk(path):
   for dirname in sorted(dirs):
        print(dirname)
Run Code Online (Sandbox Code Playgroud)

(注意,dirnames是字符串而不是int,所以将sorted(dirs)它们排序为字符串 - 这是一次所需的.

正如Alfe和Ciro Santilli指出的那样,如果您希望按排序顺序递归目录,那么dirs 就地修改:

for root, dirs, files in os.walk(path):
   dirs.sort()
   for dirname in dirs:
        print(os.path.join(root, dirname))
Run Code Online (Sandbox Code Playgroud)

你可以自己测试一下:

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)
Run Code Online (Sandbox Code Playgroud)

版画

1
10
11
12
2
20
21
22
3
30
31
32
Run Code Online (Sandbox Code Playgroud)

如果您想按数字顺序列出它们:

for dirname in sorted(dirs, key=int):
Run Code Online (Sandbox Code Playgroud)

要对字母数字字符串进行排序,请使用自然排序.

  • Python为避免记录任何可靠的顺序而避免记录任何可靠顺序的原因是它在不同的平台上使用不同的函数(`FindNextFileW`,`DosFindNext`,`readdir`),并且这些函数本身也记录在文件系统中.平台,文件系统通常不记录订单或给你一些完全无用的东西. (5认同)
  • 我认为这不会对多级层次结构进行排序,因为`sorted`不是就地的.为此,请使用Alfe所解释的`sort`. (2认同)

Alf*_*lfe 37

os.walk()在每个步骤中产生它将在接下来的步骤中做什么.您可以在每个步骤中通过按照您希望的方式对列表进行排序来影响后续步骤的顺序.引用2.7手册:

当topdown为True时,调用者可以就地修改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
Run Code Online (Sandbox Code Playgroud)

在此之后,dirNames它们就地排序,并且相应的下一个产生的值walk将是相应的.

当然,您也可以对列表进行排序,fileNames但这不会影响任何进一步的步骤(因为文件没有后代walk将访问).

当然,你可以像unutbu的答案一样迭代这些列表的排序版本,但这不会影响walk自身的进一步发展.

未修改的值的顺序未定义os.walk,意味着它将是"任何"顺序.你不应该依赖你今天的经历.但实际上它可能是底层文件系统返回的内容.在某些文件系统中,这将按字母顺序排列.


vpu*_*nte 27

最简单的方法是对返回值进行排序os.walk(),例如:

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

  • 这将首先收集`os.walk()`传递到列表中的所有值,然后对该列表进行排序,然后运行`for`循环.此列表可能会变得非常大.收集它可能需要很长时间.有效地,`os.walk()`的生成器特性的优点被破坏了.对每个目录的结果进行就地排序(参见我的回答)可能看起来有点复杂,但我认为保持发电机优势是值得的. (11认同)
  • 我不知道为什么人们忽略这个答案,这是最干净、最简单的解决方案...... TY (4认同)
  • 不幸的是,这对我不起作用:( (2认同)
  • 我用它来对目录和文件进行排序: for subdir、dirs、sorted(os.walk(rootDir)) 中的文件: for sorted(files) 中的文件: (2认同)