os.walk按什么顺序迭代?

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

它是按数字值sorting吗?

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

还是按ASCII值sorting,就像ls给出的一样?

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

而且,我怎样才能得到一个特定的订单?

os.walk使用os.listdir 。 这里是os.listdir的文档string:

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) 

(注意dirnames是string而不是ints,所以sort sorted(dirs)它们sorting为string – 这一次是可取的。

正如Alfe和Ciro Santilli所指出的那样,如果您希望以sorting的顺序recursion dirs ,请修改dirs 中的 dirs

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

你可以自己testing一下:

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

要对字母数字string进行sorting,请使用自然sorting 。

os.walk()在每个步骤中产生它在接下来的步骤中会做的事情。 您可以在每一步中按照您希望的方式对列表进行sorting,从而影响下一步的顺序。 引用2.7手册 :

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

所以对dirNamessorting会影响它们被访问的顺序:

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

在此之后, dirNames将在dirNames进行sorting,并且下一步产生的walk值将相应地进行sorting。

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

当然,你可以像unutbu的答案所提出的那样遍历这些列表的sorting版本,但是这不会影响walk本身的进一步进展。

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

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

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