Skip to main content
  1. About
  2. For Teams
Asked
Viewed 165 times
3

I have some simple code to print out the structure of a directory. My example directory ABC contains subdirectory A containing A.txt, a subdirectory Z containing Z.txt, and a file info.txt. In real use, this will be big collection of many files and nested directories.

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

The output is:

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

How can I make it so directories are processed/printed on the top? I want the output to replicate what I see in Windows Explorer, which displays directories first, and files after.

The output I want:

ABC/
ABC/A
ABC/A/A.txt
ABC/Z
ABC/Z/Z.txt
ABC/info.txt
5
  • 1
    Append result in list and sort it with length
    Mayur
    –  Mayur
    2019-01-28 09:50:28 +00:00
    Commented Jan 28, 2019 at 9:50
  • 2
    or sort with count of path separators. (/)
    Paritosh Singh
    –  Paritosh Singh
    2019-01-28 09:51:26 +00:00
    Commented Jan 28, 2019 at 9:51
  • 1
    Both the methods might not be accurate where folder names are larger than filenames or there are files in immediate directory (which will have only 1 / while sub-directories will have more than 1.
    ParvBanks
    –  ParvBanks
    2019-01-28 09:57:38 +00:00
    Commented Jan 28, 2019 at 9:57
  • @Ben, you could just pull the for loop for printing filenames outside the loop for printing directory names (remove indentation) and that should do it.. it will first loop through the directories and then the files in the directory.
    ParvBanks
    –  ParvBanks
    2019-01-28 10:11:24 +00:00
    Commented Jan 28, 2019 at 10:11
  • @ParvBanks This will only print the files in the very last directory.
    tobias_k
    –  tobias_k
    2019-01-28 10:14:29 +00:00
    Commented Jan 28, 2019 at 10:14

1 Answer 1

3

Without storing all the files in a list and sorting that list in one way or the other, you could make a recursive function and first recurse to the next level of the directory structure before printing the files on the current level:

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

The same could also be done with a stack, but I think this way it's a little bit clearer. And yes, this will also store some directories in a list/on a stack, but not all the files but just as many as there are levels of nested directories.

Edit: This had a problem of printing any next directory on the generator, even if that's not a sub-directory but a sibling (or "uncle" or whatever). The for _ in dirnames loop should fix that, making the recursive call once for each of the subdirectories, if any. The directory itself does not have to be passed as a parameter as it will be gotten from the generator.

Sign up to request clarification or add additional context in comments.

3 Comments

Your code works great with my initial example, thank you. But testing with a different structure the output is not what I expected. Sorry to bother you. I'm expecting dir A to output first, then A.txt, then dir Z, then Z.txt. output
@BenKailon Yes, I see the problem. The recursive call will not print the next sub-directory, but just the next in the original iterator, which might be a "sibling" directory. Give me a minute...
Exactly what I was looking for! I'm not good with recursion and it's very helpful to see your comments to see how it works. Thanks!

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.