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

时间:2011-07-12 19:37:46

标签: python-3.x os.walk

我想知道是否可以在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)

当python代码点击上面的目录时,这里是输出:

ryan:~/bktest$ ~/test.py sample
CD03
CD01
CD05
CD02
CD04

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

  

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

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

3 个答案:

答案 0 :(得分:31)

是。你在循环中对dirs进行排序。

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)

答案 1 :(得分:2)

我知道这已经得到了解答,但我想补充一点细节,在评论中添加多行代码是不可能的。

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

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

答案 2 :(得分:1)

此答案并非特定于此问题,并且问题有所不同,但是无论哪种情况都可以使用该解决方案。 考虑拥有这些文件("one1.txt""one2.txt""one10.txt"),所有文件的内容都是字符串"default"

我想遍历包含这些文件的目录,并在每个文件中找到一个特定的String并将其替换为文件名。 如果您使用此处已经提及的其他方法以及其他问题(例如dirs.sort()sorted(files)sorted(dirs),则结果将是这样的:

"one1.txt"--> "one10"
"one2.txt"--> "one1"
"one10.txt" --> "one2"

但是我们希望它是:

"one1.txt"--> "one1"
"one2.txt"--> "one2"
"one10.txt" --> "one10"

我发现这种方法可以按字母顺序更改文件内容:

import re, os, fnmatch

def atoi(text):
    return int(text) if text.isdigit() else text

def natural_keys(text):
    '''
    alist.sort(key=natural_keys) sorts in human order
    http://nedbatchelder.com/blog/200712/human_sorting.html
    (See Toothy's implementation in the comments)
    '''
    return [ atoi(c) for c in re.split('(\d+)', text) ]

def findReplace(directory, find, replace, filePattern):
    count = 0
    for path, dirs, files in sorted(os.walk(os.path.abspath(directory))):
        dirs.sort()
        for filename in sorted(fnmatch.filter(files, filePattern), key=natural_keys):
            count = count +1
            filepath = os.path.join(path, filename)
            with open(filepath) as f:
                s = f.read()
            s = s.replace(find, replace+str(count)+".png")
            with open(filepath, "w") as f:
                f.write(s)

然后运行此行:

findReplace(os.getcwd(), "default", "one", "*.xml")