【问题标题】:os.walk but with directories on top?os.walk 但顶部有目录?
【发布时间】:2019-01-28 09:48:41
【问题描述】:

我有一些简单的代码可以打印出目录的结构。 我的示例目录ABC 包含子目录A,其中包含A.txt,一个子目录Z 包含Z.txt,以及一个文件info.txt。在实际使用中,这将是许多文件和嵌套目录的大集合。

import os
topdir = 'ABC/'
for dirpath, dirnames, files in os.walk(topdir):
    print(os.path.join(dirpath))
    for name in files:
        print(os.path.join(dirpath, name))

输出是:

ABC/
ABC/info.txt
ABC/A
ABC/A/A.txt
ABC/Z
ABC/Z/Z.txt

如何才能使目录在顶部处理/打印? 我希望输出复制我在 Windows 资源管理器中看到的内容,它首先显示目录,然后显示文件。

我想要的输出:

ABC/
ABC/A
ABC/A/A.txt
ABC/Z
ABC/Z/Z.txt
ABC/info.txt

【问题讨论】:

  • 在列表中追加结果并按长度排序
  • 或使用路径分隔符的数量进行排序。 (/)
  • 这两种方法可能在folder names are larger than filenames 或直接目录中有文件时都不准确(其中只有1 个/,而子目录将有1 个以上。
  • @Ben,您可以将for 循环用于在循环之外打印文件名以打印目录名称(删除缩进),并且应该这样做..它将首先循环遍历目录,然后目录中的文件。
  • @ParvBanks 这只会打印最后一个目录中的文件。

标签: python python-3.x


【解决方案1】:

无需将所有文件存储在列表中并以一种或另一种方式对该列表进行排序,您可以创建一个递归函数并首先递归到目录结构的下一级,然后再打印当前级别的文件:

def print_dirs(directories):
    try:
        dirpath, dirnames, files = next(directories)
        print(dirpath)              # print current path; no need for join here
        for _ in dirnames:          # once for each sub-directory...
            print_dirs(directories) # ... recursively call generator
        for name in files:          # now, print files in current directory
            print(os.path.join(dirpath, name))
    except StopIteration:
        pass

print_dirs(os.walk(topdir))

堆栈也可以这样做,但我认为这样会更清晰一些。是的,这也会将一些目录存储在列表中/堆栈上,但不是所有文件,而是与嵌套目录的级别一样多。

编辑:这有在生成器上打印 any 下一个目录的问题,即使那不是子目录而是兄弟(或“叔叔”或其他)。 for _ in dirnames 循环应该解决这个问题,如果有的话,对每个子目录进行一次递归调用。目录本身不必作为参数传递,因为它会从生成器中获取。

【讨论】:

  • 您的代码非常适合我最初的示例,谢谢。但是用不同的结构测试输出不是我所期望的。抱歉打扰你。我希望首先输出 dir A,然后是 A.txt,然后是 dir Z,然后是 Z.txt。 output
  • @BenKailon 是的,我明白了问题所在。递归调用不会打印下一个子目录,而只会打印原始迭代器中的下一个子目录,这可能是一个“兄弟”目录。给我一分钟...
  • 正是我想要的!我不擅长递归,看看你的 cmets 看看它是如何工作的非常有帮助。谢谢!
猜你喜欢
  • 2012-10-25
  • 2010-09-18
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
相关资源
最近更新 更多