Python os.walk 以什么顺序迭代?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18282370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:23:26  来源:igfitidea点击:

In what order does os.walk iterates iterate?

pythonsortingos.walk

提问by Vahid Mirjalili

I am concerned about the order of files and directories given by os.walk(). If I have these directories, 1, 10, 11, 12, 2, 20, 21, 22, 3, 30, 31, 32, what is the order of the output list?

我担心os.walk(). 如果我有这些目录, 1, 10, 11, 12, 2, 20, 21, 22, 3, 30, 31, 32, 输出列表的顺序是什么?

Is it sorted by numeric values?

是否按数值排序?

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

Or sorted by ASCII values, like what is given by ls?

或按 ASCII 值排序,例如由ls?

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

Additionally, how can I get a specific sort?

另外,我怎样才能得到一个特定的排序?

采纳答案by unutbu

os.walkuses os.listdir. Here is the docstring for os.listdir:

os.walk使用os.listdir. 这是文档字符串os.listdir

listdir(path) -> list_of_strings

Return a list containing the names of the entries in the directory.

path: path of directory to list

The list is in arbitrary order. It does not include the special entries '.' and '..' even if they are present in the directory.

listdir(path) -> list_of_strings

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

path: path of directory to list

该列表的顺序是任意的。它不包括特殊条目“.” 和 '..' 即使它们存在于目录中。

(my emphasis).

(我的重点)。

You could, however, use sortto ensure the order you desire.

但是,您可以使用sort来确保您想要的顺序。

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

(Note the dirnames are strings not ints, so sorted(dirs)sorts them as strings -- which is desirable for once.

(请注意,目录名是字符串而不是整数,因此将sorted(dirs)它们作为字符串进行排序——这是一次可取的。

As Alfe and fxsc point out, if you want the directories to be recursedin sorted order, then modify dirsin-place:

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

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


You can test this yourself:

你可以自己测试一下:

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)

prints

印刷

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

If you wanted to list them in numeric order use:

如果您想按数字顺序列出它们,请使用:

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

To sort alphanumeric strings, use natural sort.

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

回答by Alfe

os.walk()yields in each step what it will do in the next steps. You can in each step influence the order of the next steps by sorting the lists the way you want them. Quoting the 2.7 manual:

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

When topdown is True, the caller can modify the dirnames list in-place (perhaps using del or slice assignment), and walk() will only recurse into the subdirectories whose names remain in dirnames; this can be used to prune the search, impose a specific order of visiting

当 topdown 为 True 时,调用者可以就地修改 dirnames 列表(可能使用 del 或 slice 赋值),而 walk() 只会递归到名称保留在 dirnames 中的子目录;这可用于修剪搜索,强加特定的访问顺序

So sorting the dirNameswill influence the order in which they will be visited:

所以排序dirNames将影响他们将被访问的顺序:

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

After this, the dirNamesare sorted in-place and the next yielded values of walkwill be accordingly.

在此之后,dirNames就地排序,下一个产生的值walk将相应地。

Of course you also can sort the list of fileNamesbut that won't influence any further steps (because files don't have descendants walkwill visit).

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

And of course you can iterate through sorted versions of these lists as unutbu's answer proposes, but that won't influence the further progress of the walkitself.

当然,您可以按照 unutbu 的回答建议遍历这些列表的排序版本,但这不会影响其walk本身的进一步进展。

The unmodified order of the values is undefined by os.walk, meaning that it will be "any" order. You should not rely on what you experience today. But in fact it will probably be what the underlying file system returns. In some file systems this will be alphabetically ordered.

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

回答by vpuente

The simplest way is to sort the return values of os.walk(), e.g. using:

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

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