我可以强制python3的os.walk按字母顺序访问目录吗?怎么样?

rya*_*n_m 25 os.walk python-3.x

我想知道是否可以在python3中强制os.walk按字母顺序访问目录.例如,这是一个目录和一些将遍历此目录的代码:

ryan:~/bktest$ ls -1 sample
CD01
CD02
CD03
CD04
CD05

--------

def main_work_subdirs(gl):
    for root, dirs, files in os.walk(gl['pwd']):
        if root == gl['pwd']:
            for d2i in dirs:
                print(d2i)
Run Code Online (Sandbox Code Playgroud)

当python代码点击上面的目录时,输出如下:

ryan:~/bktest$ ~/test.py sample
CD03
CD01
CD05
CD02
CD04
Run Code Online (Sandbox Code Playgroud)

我想强迫步行按字母顺序访问这些目录01, 02 ... 05.在python3 doc中os.walk,它说:

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

这是否意味着我可以强加一个按字母顺序排列的访问顺序os.walk?如果是这样,怎么样?

Len*_*bro 36

是.你在循环中排序.

def main_work_subdirs(gl):
    for root, dirs, files in os.walk(gl['pwd']):
        dirs.sort()
        if root == gl['pwd']:
            for d2i in dirs:
                print(d2i)
Run Code Online (Sandbox Code Playgroud)

  • 我认为值得一提的一个微妙之处是:它依赖于`dirs`对象返回被修改到位,因为`os.walk`继续使用该列表.因此,如果你传递`topdown = False`,那么dirs在其内容之后产生*,那么它将无法正常工作.类似地,如果你做了`dirs = sorted(dirs)`而不是`dirs.sort()`,那么它也无法正常工作. (11认同)
  • 请注意,`dirs`是一个列表,而不是生成器. (7认同)
  • @ryan_m:那就是你所能做的一切.但是,由于迭代的下一步直到你完成第一步之后才生成,所以它允许这样的技巧.:-) (2认同)
  • 好点@wim更多关于sorted(bx)和x.sort()之间的区别:/sf/ask/1570966491/ Between-sortedlist-vs-list-sort (2认同)

kei*_*ley 6

我知道这已经得到了回答,但我想添加一个小细节,在评论中添加多于一行的代码是不可靠的。

除了希望对目录进行排序之外,我还希望对文件进行排序,以便通过“gl”进行的迭代是一致且可预测的。要做到这一点,还需要一种方式:

for root, dirs, files in os.walk(gl['pwd']):
  dirs.sort()
  for filename in sorted(files):
    print(os.path.join(root, filename))
Run Code Online (Sandbox Code Playgroud)

并且,有了更多地了解 Python 的好处,一种不同的(更好的)方式:

from pathlib import Path
# Directories, per original question.
[print(p) for p in sorted(Path(gl['pwd']).glob('**/*')) if p.is_dir()]
# Files, like I usually need.
[print(p) for p in sorted(Path(gl['pwd']).glob('**/*')) if p.is_file()]
Run Code Online (Sandbox Code Playgroud)